汉诺塔问题

题目

开始时所有圆盘都放在左边的柱子上,按照汉诺塔游戏的要求我们要把所有的圆盘都移到右边的柱子上,请实现一个函数打印最优移动轨迹。

给定一个int n,表示有n个圆盘。请返回一个string数组,其中的元素依次为每次移动的描述。描述格式为: move from [left/mid/right] to [left/mid/right]。

输入:1
返回:move from left to right

思路

  • n 层汉诺塔问题,要解决的是
    • 把 1 ~ n -1 层圆盘从left 移动到 mid ,可以借助 right
    • 最后把第 n 层移动到 right
  • n - 1 层汉诺塔问题,要解决的是
    • 把 1 ~ n - 2 层圆盘从 mid 移动到 left,可以借助的是 right
    • 最后把第 n - 1 层移动到 right
  • n - 2 层汉诺塔问题,要解决的是
    • 把 1 ~ n - 3 层圆盘从 left 移动到 mid,可以借助的是 right
    • 最后把第 n - 2 层移动 right
  • n - 3 层汉诺塔问题,要解决的是
    • 把 1 ~ n - 4 层圆盘从 mid 移动 left,可以借助的是 right
    • 最后把第 n - 3 层移动到 right
  • ...

可以发现这是两个过程不断在反复循环,都是借助 right,来把临时的头上的一堆塔移动到 left / mid,再从 left / mid 移动最底下的圆盘到 right 中去

最后,如果只剩下一个了,直接把它从 left 移动到 right 去

思考这个问题的重点是,left mid 和 right 是三个相对概念位置,在每一次过程都是相对改变的

class Hanoi {
    public ArrayList<String> getSolution(int n) {
        ArrayList<String> list = new ArrayList<>();
        move(n, "left", "right", "mid", list);
        return list;
    }

    private void move(int n,
                      String from,
                      String to,
                      String help,
                      ArrayList<String> list) {
        if (n == 1) {
            list.add("move from" + from + " to " + to);
        } else {
            move(n - 1, from, help, to, list);
            list.add("move from" + from + " to " + to);
            move(n - 1, help, to, from, list);
        }
    }
}

总结

今天复习左神的递归与 dp 课

全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务