package class18; public class Code01_HanoiProblem { public static int step1(int[] arr) { if (arr == null || arr.length == 0) { return -1; } return process(arr, arr.length - 1, 1, 2, 3); } // 目标是: 把0~i的圆盘,从from全部挪到to上 // 返回,根据arr中的状态arr[0..i],它是最优解的第几步? // f(i, 3 , 2, 1) f(i, 1, 3, 2) f(i, 3, 1, 2) public static int process(int[] arr, int i, int from, int other, int to) { if (i == -1) { return 0; } if (arr[i] != from && arr[i] != to) { return -1; } if (arr[i] == from) { // 第一大步没走完 return process(arr, i - 1, from, to, other); } else { // arr[i] == to // 已经走完1,2两步了, int rest = process(arr, i - 1, other, from, to); // 第三大步完成的程度 if (rest == -1) { return -1; } return (1 << i) + rest; } } public static int step2(int[] arr) { if (arr == null || arr.length == 0) { return -1; } int from = 1; int mid = 2; int to = 3; int i = arr.length - 1; int res = 0; int tmp = 0; while (i >= 0) { if (arr[i] != from && arr[i] != to) { return -1; } if (arr[i] == to) { res += 1 << i; tmp = from; from = mid; } else { tmp = to; to = mid; } mid = tmp; i--; } return res; } public static int kth(int[] arr) { int N = arr.length; return step(arr, N - 1, 1, 3, 2); } // 0...index这些圆盘,arr[0..index] index+1层塔 // 在哪?from 去哪?to 另一个是啥?other // arr[0..index]这些状态,是index+1层汉诺塔问题的,最优解第几步 public static int step(int[] arr, int index, int from, int to, int other) { if (index == -1) { return 0; } if (arr[index] == other) { return -1; } // arr[index] == from arr[index] == to; if (arr[index] == from) { return step(arr, index - 1, from, other, to); } else { int p1 = (1 << index) - 1; int p2 = 1; int p3 = step(arr, index - 1, other, to, from); if (p3 == -1) { return -1; } return p1 + p2 + p3; } } public static void main(String[] args) { int[] arr = { 3, 3, 2, 1 }; System.out.println(step1(arr)); System.out.println(step2(arr)); System.out.println(kth(arr)); } }