modify code

master
algorithmzuo 2 years ago
parent f552f88a5d
commit 4c12cfd6d5

@ -1,74 +1,141 @@
package class_2021_12_3_week;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Arrays;
import java.util.List;
// leetcode增加了新的数据
// 导致原来的实现不通过了
// 一怒之下,做了各种优化
// 思路完全和课上讲的一样,就是实现完全重来了
// 目前打败100%的人
// 测试链接 : https://leetcode.com/problems/cut-off-trees-for-golf-event/
public class Code04_CutOffTreesForGolfEvent {
public static int MAXN = 51;
public static int MAXM = 51;
public static int LIMIT = MAXN * MAXM;
public static int[][] f = new int[MAXN][MAXM];
public static int[][] arr = new int[LIMIT][3];
public static int[] move = new int[] { 1, 0, -1, 0, 1 };
public static int n, m;
// 为了快,手撸双端队列
public static int[][] deque = new int[LIMIT][3];
// 双端队列的头、尾、大小
public static int l, r, size;
// 初始化双端队列
public static void buildDeque() {
l = -1;
r = -1;
size = 0;
}
// 双端队列从头部弹出
public static int[] pollFirst() {
int[] ans = deque[l];
if (l < LIMIT - 1) {
l++;
} else {
l = 0;
}
size--;
if (size == 0) {
l = r = -1;
}
return ans;
}
// 双端队列从头部加入
public static void offerFirst(int x, int y, int d) {
if (l == -1) {
deque[0][0] = x;
deque[0][1] = y;
deque[0][2] = d;
l = r = 0;
} else {
int fill = l == 0 ? (LIMIT - 1) : (l - 1);
deque[fill][0] = x;
deque[fill][1] = y;
deque[fill][2] = d;
l = fill;
}
size++;
}
// 双端队列从尾部加入
public static void offerLast(int x, int y, int d) {
if (l == -1) {
deque[0][0] = x;
deque[0][1] = y;
deque[0][2] = d;
l = r = 0;
} else {
int fill = (r == LIMIT - 1) ? 0 : (r + 1);
deque[fill][0] = x;
deque[fill][1] = y;
deque[fill][2] = d;
r = fill;
}
size++;
}
public static int cutOffTree(List<List<Integer>> forest) {
int n = forest.size();
int m = forest.get(0).size();
// [ [3,5,2], [1,9,4] , [2,6,10] ]
// 低 中 高
ArrayList<int[]> cells = new ArrayList<>();
n = forest.size();
m = forest.get(0).size();
int cnt = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
int val = forest.get(i).get(j);
if (val > 1) {
cells.add(new int[] { i, j, val });
int value = forest.get(i).get(j);
f[i][j] = value > 0 ? 1 : 0;
if (value > 1) {
arr[cnt][0] = value;
arr[cnt][1] = i;
arr[cnt++][2] = j;
}
}
}
cells.sort((a, b) -> a[2] - b[2]);
int ans = 0, lastR = 0, lastC = 0;
for (int[] cell : cells) {
int step = bestWalk(forest, lastR, lastC, cell[0], cell[1]);
Arrays.sort(arr, 0, cnt, (a, b) -> a[0] - b[0]);
int ans = 0;
for (int i = 0, x = 0, y = 0, block = 2; i < cnt; i++, block++) {
int toX = arr[i][1];
int toY = arr[i][2];
int step = walk(x, y, toX, toY, block);
if (step == -1) {
return -1;
}
ans += step;
lastR = cell[0];
lastC = cell[1];
forest.get(lastR).set(lastC, 1);
x = toX;
y = toY;
}
return ans;
}
public static int[] next = { -1, 0, 1, 0, -1 };
// 0 1 2 3 4
// i
// 行 + next[i-1]
// 列 + next[i]
// i == 1 -> 上
// i == 2 -> 右
// i == 3 -> 下
// i == 4 -> 左
public static int bestWalk(List<List<Integer>> forest, int sr, int sc, int tr, int tc) {
int n = forest.size();
int m = forest.get(0).size();
boolean[][] seen = new boolean[n][m];
LinkedList<int[]> deque = new LinkedList<>();
deque.offerFirst(new int[] { 0, sr, sc });
while (!deque.isEmpty()) {
int[] cur = deque.pollFirst();
int step = cur[0], r = cur[1], c = cur[2];
if (r == tr && c == tc) {
return step;
}
seen[r][c] = true;
for (int i = 1; i < 5; i++) { // (r,c) 上下左右,全试试!
int nr = r + next[i - 1];
int nc = c + next[i];
if (nr >= 0 && nr < n && nc >= 0 && nc < m && !seen[nr][nc] && forest.get(nr).get(nc) > 0) {
int[] move = { step + 1, nr, nc };
// 更近的话
if ((i == 1 && r > tr) || (i == 2 && c < tc) || (i == 3 && r < tr) || (i == 4 && c > tc)) {
deque.offerFirst(move);
} else { // 更远的话,放到尾部!
deque.offerLast(move);
public static int walk(int a, int b, int c, int d, int block) {
buildDeque();
offerFirst(a, b, 0);
while (size > 0) {
int[] cur = pollFirst();
int x = cur[0];
int y = cur[1];
int distance = cur[2];
if (f[x][y] != block) {
f[x][y] = block;
if (x == c && y == d) {
return distance;
}
for (int i = 1; i < 5; i++) {
int nextX = x + move[i];
int nextY = y + move[i - 1];
if (nextX >= 0 && nextX < n && nextY >= 0 && nextY < m && f[nextX][nextY] != 0
&& f[nextX][nextY] != block) {
if ((i == 1 && y < d) || (i == 2 && x > c) || (i == 3 && y > d) || (i == 4 && x < c)) {
// 离的更近
offerFirst(nextX, nextY, distance + 1);
} else {
// 离的更远
offerLast(nextX, nextY, distance + 1);
}
}
}
}

Loading…
Cancel
Save