汉诺塔问题

问题描述

牛客网汉诺塔问题

PTA汉诺塔问题

百练汉诺塔问题

递归实现

void hanoi_recursively(int n, char from, char via, char to) {
	if (n == 1) {
		printf("%c -> %c\n", from, to);
	} else {
		hanoi_recursively(n - 1, from, to, via);
		hanoi_recursively(1, from, via, to);
		hanoi_recursively(n - 1, via, from, to);
	}
}

非递归实现

#include <stack>
#include <stdio.h>
using namespace std;

struct Problem {
    int n;
    char from, via, to;
    Problem (int nn, char f, char v, char t) : n(nn), from(f), via(v), to(t) {}
};

int main() {
    int N;
    scanf("%d", &N);
    stack<Problem> stk;
    stk.push(Problem(N, 'a', 'b', 'c'));
    while(!stk.empty()) {
        Problem p = stk.top();
        stk.pop();
        if (p.n == 1) {
            printf("%c -> %c\n", p.from, p.to);
        } else {
        	//注意这里的压栈顺序和递归求解时是相反的
            stk.push(Problem(p.n - 1, p.via, p.from, p.to));
            stk.push(Problem(1, p.from, p.via, p.to));
            stk.push(Problem(p.n - 1, p.from, p.to, p.via));
        }
    }
    return 0;
}

问题解答

牛客网:

#include <vector>
class Solution {
public:
    void hanoi(int n, string from, string via, string to, vector<string>& res) {
        if (n == 1) {
            res.push_back("move from " + from + " to " + to);
        } else {
            hanoi(n - 1, from, to, via, res);
            hanoi(1, from, via, to, res);
            hanoi(n - 1, via, from, to, res);
        }
    }
    vector<string> getSolution(int n) {
        // write code here
        vector<string> res;
        hanoi(n, "left", "mid", "right", res);
        return res;
    }
};

百练:

#include <stdio.h>
using namespace std;

void hanoi(int n, char from, char via, char to, int id) {
    if (n == 1) {
        printf("%d:%c->%c\n", id, from, to);
    } else {
        hanoi(n - 1, from, to, via, n - 1);
        hanoi(1, from, via, to, n);		//问题的规模=最后一个盘子的编号
        hanoi(n - 1, via, from, to, n - 1);
    }
}

int main() {
    char a, b, c;
    int n;
    scanf("%d %c %c %c", &n, &a, &b, &c);
    hanoi(n, a, b, c, n);
    return 0;
}

PTA:参考上方的“非递归实现”

复杂度分析

假设有n片,移动次数是f(n),显然f(1)=1,f(2)=3,f(3)=7

根据递归结构有: f ( k + 1 ) = 2 ∗ f ( k ) + 1 f(k + 1) = 2*f(k) + 1 f(k+1)=2f(k)+1,下面求解这个递归式:

f ( k + 1 ) + 1 = 2 ∗ ( f ( k ) + 1 ) f(k + 1) + 1 = 2*(f(k) + 1) f(k+1)+1=2(f(k)+1)

于是:

f ( k + 1 ) + 1 f ( k ) + 1 = 2 \frac{f(k + 1) + 1 }{f(k) + 1} = 2 f(k)+1f(k+1)+1=2

f ( k ) + 1 f(k) + 1 f(k)+1为等比数列,于是 f ( k ) = 2 k − 1 f(k) = 2^k - 1 f(k)=2k1

所以汉诺塔问题的时间复杂度和空间复杂度均为 O ( 2 n ) O(2^n) O(2n)

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值