编程语言
首页 > 编程语言> > python leetcode 动态规划 递归算法 汉诺塔

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