You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

98 lines
2.2 KiB

2 years ago
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
// 已经走完12两步了
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));
}
}