汉诺塔问题采用递归法分析
问题抽象
f(n, a, b, c)表示将n个盘子(从上到下分别记作1,2,3...n)从a柱借助b柱移动到c柱
递归公式
f(n, a, b, c) = f(n - 1, a, c, b) + "mov number n to c" + f(n - 1, b, a, c)
f(1, a, b, c) = "mov number 1 to c"
说明:这里的等号与加号为抽象表示,加号不具有交换律,加号表示先完成左边,再完成右边
如果需要计算移动次数的话,f(n - 1, a, c, b)与f(n - 1, b, a, c)是相等的,所以f(n) = 2f(n-1) + 1, f(1) = 1
注意点
将问题由F(n)缩减到F(n-1)的时候,一定要考查F(n-1)是否与F(n)等价。
错误示例:
f(n, a, b, c) = "mov number 1 to b" + f(n - 1, a, b, c) + "mov number 1 to c"
错误原因:将1号盘移动到b柱后,f(n - 1, a, b, c)与f(n, a, b, c)是不等价的,
因为这时b上放了个1号盘,1号盘上不能再放任何盘,要将n-1个盘从a借助b移动到c是行不通的
class Solution { public: void search(int n, const string &src, const string &by, const string &dest) { string str("move from " + src + " to " + dest); if (n == 1) { m_strvec.push_back(str); return; } search(n - 1, src, dest, by); m_strvec.push_back(str); search(n - 1, by, src, dest); } vector<string> getSolution(int n) { m_strvec.clear(); if (n > 0) { search(n, "left", "mid", "right"); } return m_strvec; } private: vector<string> m_strvec; };