递归回溯分治--13-汉诺塔[简单]

问题描述(简化)

Hanoi塔问题。图中有A、B、C三根柱子,在A柱上放着n个圆盘,其中小圆盘放在大圆盘的上边。从A柱将这些圆盘移到C柱上去,在移动和放置时允许使用B柱,但不能把大盘放到小盘的下面。设计算法解决此问题,分析算法复杂度。

思路

对于本题,递归的方法比较好理解。假设有n个盘子需要从A移动到C,总步数为total_steps。

a) n=1,此时只有一个盘子需要移动,直接从A移动到C即可。total_steps=1。

b) n=2,此时需要先将最小的盘子放在B上,再将较大的盘子移动到C上,最后将最小的盘子移动到C上。total_steps=3。

c) n=3,此时假设A柱从上到下共1、2、3个盘子。步骤:1——>C、2——>B、1——>B、3——>C、1——>A、2——>C、1——>C,total_steps=7。

d) 上述过程可推广。对于n个盘子而言,需要先将A柱上的(n-1)个盘子移动到B柱,再将最大的一个移动到C,最后将(n-1)个盘子从B移动到C柱子:

  • n = 1 时,直接把盘子从 A 移到 C;
  • n > 1 时,
    • 先把上面 n - 1 个盘子从 A 移到 B(子问题,递归);
    • 再将最大的盘子从 A 移到 C;
    • 再将 B 上 n - 1 个盘子从 B 移到 C(子问题,递归)。

时间复杂度分析:

当盘子个数为n时,需要T(n)步

使用递归求解后,T(n)被分解为两个子问题,每个子问题为:T(n-1)。

得递推公式:T(n)=2T(n-1)+1

根据递推公式可得时间复杂度为:O(n)=2^n

用下述代码实现:

def hanoi(count):
    move_one_dish = 1
    if count == 1:
        return move_one_dish
    total_steps = hanoi(count-1)*2 + move_one_dish
    return total_steps
print(hanoi(3))

原题

力扣

在经典汉诺塔问题中,有 3 根柱子及 N 个不同大小的穿孔圆盘,盘子可以滑入任意一根柱子。一开始,所有盘子自上而下按升序依次套在第一根柱子上(即每一个盘子只能放在更大的盘子上面)。移动圆盘时受到以下限制:

(1) 每次只能移动一个盘子;

(2) 盘子只能从柱子顶端滑出移到下一根柱子;

(3) 盘子只能叠在比它大的盘子上。

请编写程序,用栈将所有盘子从第一根柱子移到最后一根柱子。你需要原地修改栈。A中盘子的数目不大于14个。

class Solution {
public:
    void hanota(vector<int>& A, vector<int>& B, vector<int>& C) {
        int size=A.size();
        move(size,A,B,C);
    }
    //move函数表示将A的size个通过B移动到C
    void move(int size, vector<int>& A, vector<int>& B, vector<int>& C) {
        if(size==1) {
            C.push_back(A.back());
            A.pop_back();
            return;
        }
        move(size-1,A,C,B); //将A上面n-1个通过C移动到B
        C.push_back(A.back());
        A.pop_back();
        move(size-1,B,A,C); //将B上面n-1个通过空的A移动到C
    }
};

  • 1
    点赞
  • 1
    收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页
评论

打赏作者

mate595

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值