zoukankan      html  css  js  c++  java
  • 【Leetcode刷题】汉诺塔

    https://leetcode-cn.com/problems/hanota-lcci/

    先将最底层圆盘之上的圆盘看做一个整体。汉诺塔问题的本质是

    1. 将最底层圆盘之上的圆盘全部放到辅助柱上
    2. 将最底层圆盘放到目标柱上
    3. 递归地处理辅助柱上的圆盘

    而第一步又可以变成一个目标柱为辅助柱的汉诺塔问题,即self.hanota(A[1:], C, B)

    但是要注意这样写是错误的,因为切片操作产生了一个新的对象,导致不会直接修改到A

    因此,需要一个索引记录下A需要处理到哪个位置

    class Solution(object):
        def hanota(self, A, B, C):
            """
            :type A: List[int]
            :type B: List[int]
            :type C: List[int]
            :rtype: None Do not return anything, modify C in-place instead.
            """
            # self.hanota(A[1:], C, B) 是错误的
            # 需要一个索引记录下A需要处理到哪个位置
            def move(n, a, b, c):
                # 索引为0表示A中没需要处理的元素了
                if n == 0:
                    return
                # 1. 将最底层圆盘之上的圆盘全部放到辅助柱B上
                move(n-1, a, c, b)
                # 2. 将最底层圆盘放到目标柱上
                c.append(a.pop())
                # 3. 将辅助柱B上的圆盘移到目标柱
                move(n-1, b, a, c)
    
            # 因为索引为0表示A中没有需要处理的元素
            # 因此n初始化为len(A),遍历完A中所有元素后n刚好是0
            move(len(A), A, B, C)
    
    • 时间复杂度:O(2n)。

      推导:

      由于move函数的意义是将A中元素逐个移到C中,因此运算次数与n有关,设move函数的运算次数为T(n),则需要T(n-1)步将最底层圆盘之上的圆盘全部放到辅助柱B上,一步将最底层圆盘放到目标柱上,还需要T(n-1)步将辅助柱B上的圆盘移到目标柱。

      由此可得T(n) = 2T(n-1) + 1

      等式两边加一得T(n) + 1 = 2T(n-1) + 2

      因此可得T(n)是一个公比为2的等比数列,即T(n) = 2n

    • 空间复杂度:O(n)。递归深度是n

  • 相关阅读:
    vb.net structure 定义静态数组
    调色板原理 & 编程
    CView::OnPreparePrinting
    MFC单文档程序架构解析
    基于Eclipse远程调试解决的预上线首页打开特别慢的问题
    Shiro Filter引发的思考
    Shiro Filter中利用Callable和Runnable的委派模式
    Shiro DefaultFilter
    防止Form表单重复提交的客户端及服务器端的方式
    Shiro Filter的设计概念
  • 原文地址:https://www.cnblogs.com/luozx207/p/13409410.html
Copyright © 2011-2022 走看看