持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第22天,点击查看活动详情
面试题 08.06. 汉诺塔问题
在经典汉诺塔问题中,有 3 根柱子及 N 个不同大小的穿孔圆盘,盘子可以滑入任意一根柱子。一开始,所有盘子自上而下按升序依次套在第一根柱子上(即每一个盘子只能放在更大的盘子上面)。移动圆盘时受到以下限制: (1) 每次只能移动一个盘子; (2) 盘子只能从柱子顶端滑出移到下一根柱子; (3) 盘子只能叠在比它大的盘子上。
请编写程序,用栈将所有盘子从第一根柱子移到最后一根柱子。
你需要原地修改栈。
「示例1:」
输入:A = [2, 1, 0], B = [], C = []
输出:C = [2, 1, 0]
「示例2:」
输入:A = [1, 0], B = [], C = []
输出:C = [1, 0]
「提示:」
A中盘子的数目不大于14个。
解题思路
// 第一种
不断递归:
将A中的n-1个移动到B
将A剩余的1个移动到C
将B中的n-1个移动到C
当只剩1个时,直接将A剩余的1个移动到C,结束递归
// 第二种
汉诺塔主要思路
1.如果只有一个需要移动,直接将A的那个盘子移到c
2.如果有大于1个即n个需要移动,将前n-1个借助c移动到b,把最后一个移动到c
3.再将在b上的n-1个通过a移动到c
代码实现
// 第一种
const hanota = (A, B, C) => {
const n = A.length;
// 将A中的n个移动到C
const move = (n, A, B, C) => {
if (n === 1) {
C.push(A.pop());
return;
}
// 将A中的n-1个移动到B
move(n - 1, A, C, B);
// 将A剩余的一个移动到C
C.push(A.pop());
// 将B中的n-1个移动到C
move(n - 1, B, A, C);
};
move(n, A, B, C);
};
// 第二种
/**
* @param {number[]} A
* @param {number[]} B
* @param {number[]} C
* @return {void} Do not return anything, modify C in-place instead.
*/
var hanota = function(A, B, C) {
let len=A.length;
const rec=(m,a,b,c)=>{
if(m===1){
c.push(a.pop())
}
else{
rec(m-1,a,c,b)
c.push(a.pop())
rec(m-1,b,a,c)
}
}
rec(len,A,B,C)
};
如果你对这道题目还有疑问的话,可以在评论区进行留言;