python leetcode 动态规划 递归算法 汉诺塔
作者:互联网
题目链接
https://leetcode-cn.com/problems/hanota-lcci/
题目介绍
面试题 08.06. 汉诺塔问题
在经典汉诺塔问题中,有 3 根柱子及 N 个不同大小的穿孔圆盘,盘子可以滑入任意一根柱子。一开始,所有盘子自上而下按升序依次套在第一根柱子上(即每一个盘子只能放在更大的盘子上面)。移动圆盘时受到以下限制:
(1) 每次只能移动一个盘子;
(2) 盘子只能从柱子顶端滑出移到下一根柱子;
(3) 盘子只能叠在比它大的盘子上。
请编写程序,用栈将所有盘子从第一根柱子移到最后一根柱子。
你需要原地修改栈。
示例1:
输入:A = [2, 1, 0], B = [], C = []
输出:C = [2, 1, 0]
pure recursition:
class Solution:
def hanota(self, A: List[int], B: List[int], C: List[int]) -> None:
"""
Do not return anything, modify C in-place instead.
"""
n = len(A)
def hano(n, A, B, C):
if n == 1:
C.append(A.pop())
else:
hano(n - 1, A, C, B)
hano(1, A, B, C)
hano(n - 1, B, A, C)
return C
return hano(n, A, B, C)
思路
举个例子,
如果A柱上只有一个圆盘,你会立马套到C上
如果有两个呢,你会先把第一个移到B上,将A剩下来的移到C再把B上的移到C上
那如果有n个呢,是不是先把n-1个移到B上,把A剩下来的移到C上,再把B上的直接套到C上
细节注意点
n == 1时将元素添加到C上之后别忘了取出那个元素
另外,pop会取出来并且存储下来,a.pop(),一般括号里的参数为索引值,如果没有默认为*-1*
在题解中套函数,别忘了需要两次return
暴力解法
思路
本题要的不就是将C变成A吗,两个又都是列表。
class Solution:
def hanota(self, A: List[int], B: List[int], C: List[int]) -> None:
"""
Do not return anything, modify C in-place instead.
"""
#first
while A:
C.append(A.pop(0))
return C
#second
C[:] = A
return C
优化
无论空间还是时间复杂度都是下面的更好。
本题也是递归题,告诉我们应该从最简单的出发。
拓展
虽然大多数时候不会用到纯递归,因为它时间复杂度是指数型的,但是它的思想很值得学习。
无论是人类社会的演变,还是知识的学习,都是从最开始的基例开始
然而,现代大多数时候人们往往过于急切和功利化,忽视了基例的建设,就拿代码来说,后面写的天花乱坠,到头来,一开始就直接报错。
学知识也是一样,少即是多,将所学的全部掌握好过所有都学的一知半解。
第一性原理,回过头来想想,当后面变化的越来越复杂的时候,其实它的本质与一开始最简单的基例是没有区别的,这告诉我们解决问题的时候,应该不断回溯,回到问题最开始的地方,去解决本质的东西,后面再复杂也一样轻轻松松解决。
标签:柱子,return,python,List,int,汉诺塔,hano,盘子,leetcode 来源: https://www.cnblogs.com/sherlcok314159/p/14340032.html