携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第 6 天,点击查看活动详情
汉诺塔问题
在经典汉诺塔问题中,有 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]
示例3:
输入:A = [5, 2, 0], B = [], C = []
输出:C = [5, 2, 0]
提示:
- A中盘子的数目不大于14个。
思路分析
- 使用递归的方式来解决,如果想使
A中的盘子都移动到C中,那么首先将A中的n-1个移动到B,然后将A中剩余一个的移动到C,然后再将B中的n-1个移动到C; - 等到
A中剩余1个时,将A中的直接移到C即可; - 定义一个
move方法,接收(len, A, B, C)的入参,表示将A中的len个以B做中介移动到C中; - 那么,按照步骤1、2的描述,若
len === 1时,直接移动到C上即可; - 否则,需要将
A中的len-1个移动到B,即move(len - 1, A, C, B);然后将A剩余的一个移动到C,即C.push(A.pop());然后将B中的len-1个移动到C,即move(len - 1, B, A, C)即可; - 最后调用
move方法, 即move(len, A, B, C)。
AC 代码
/**
* @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) {
const len = A.length
// 将A中的n个移动到C
const move = (len, A, B, C) => {
if (len === 1) {
C.push(A.pop())
return
}
// 将A中的n-1个移动到B
move(len - 1, A, C, B)
// 将A剩余的一个移动到C
C.push(A.pop())
// 将B中的n-1个移动到C
move(len - 1, B, A, C)
}
move(len, A, B, C)
};
结果:
- 执行结果: 通过
- 执行用时:52 ms, 在所有 JavaScript 提交中击败了95.05%的用户
- 内存消耗:41.1 MB, 在所有 JavaScript 提交中击败了14.85%的用户
- 通过测试用例:14 / 14