題目 貓和老鼠:https://leetcode-cn.com/problems/cat-and-mouse/submissions/
極大極小值,有深度搜索的感覺在。
每次新賦值都是要考慮當前狀態是極大值還是極小值,然后根據這個狀態再向上更新值。
這道題,維護兩個數組,一個是當前節點可走節點數,一個是當前節點的勝負狀態。
一開始先初始化這兩個數組,將可走節點數取該節點線條數,如果是貓就減去一條0的線路。
勝負狀態就初始化老鼠0,貓任意,老鼠贏 和 老鼠和貓同一點,貓贏 這兩種狀態點,其他節點通過后期遍歷賦值。
遍歷取到的狀態點
同時每個狀態點都要將能達到它的父節點給取出
遍歷這些父節點,將沒有狀態的點進行判斷賦值。
最后跑完的整個勝負數組的狀態就是 老鼠起點, 貓起點, 勝負狀態 的一個數組。
class Solution {
public int catMouseGame(int[][] graph) {
int N = graph.length;
final int DRAW = 0, MOUSE = 1, CAT = 2;
int[][][] degree = new int[50][50][3];
int[][][] color = new int[50][50][3];
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
degree[i][j][1] = graph[i].length;
degree[i][j][2] = graph[j].length;
for (int m: graph[j]) {
if (m == 0) {
degree[i][j][2]--;
break;
}
}
}
}
Queue<int[]> queue = new LinkedList<>();
for (int i = 0; i < N; i++) {
for (int j = 1; j <=2; j++) {
color[0][i][j] = MOUSE;
queue.add(new int[]{0, i, j, MOUSE});
if (i > 0) {
color[i][i][j] = CAT;
queue.add(new int[]{i, i, j, CAT});
}
}
}
while(!queue.isEmpty()) {
int[] node = queue.remove();
int i = node[0], j = node[1], t = node[2], c = node[3];
for (int[] parent: getParent(graph, i, j, t)) {
int i2 = parent[0], j2 = parent[1], t2 = parent[2];
if (color[i2][j2][t2] == DRAW) {
if (t2 == c) {
color[i2][j2][t2] = c;
queue.add(new int[]{i2, j2, t2, c});
} else {
degree[i2][j2][t2]--;
if (degree[i2][j2][t2] == 0) {
color[i2][j2][t2] = 3 - t2;
queue.add(new int[]{i2, j2, t2, 3 - t2});
}
}
}
}
}
return color[1][2][1];
}
private List<int[]> getParent(int[][] graph, int i, int j, int t) {
List<int[]> list = new LinkedList();
if (t == 2) {
for (int m : graph[i]) {
list.add(new int[]{m, j, 3-t});
}
} else {
for (int c : graph[j]) {
if (c > 0) {
list.add(new int[]{i, c, 3-t});
}
}
}
return list;
}
}
