【LeetCode】每日一题

62 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 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个移动到BA剩余的1个移动到CB中的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)
};

如果你对这道题目还有疑问的话,可以在评论区进行留言;