Leetcode 934 最短的桥 DFS标记+BFS寻址
C:
// 队列与栈 struct Node { int val; int depth; struct Node *next; struct Node *pre; }; struct Queue { struct Node *head; struct Node *last; int len; }; struct Queue *initQueue() { struct Queue *queue = (struct Queue *)malloc(sizeof(struct Queue)); struct Node *head = (struct Node *)malloc(sizeof(struct Node)); struct Node *last = (struct Node *)malloc(sizeof(struct Node)); head->next = last; head->pre = NULL; last->pre = head; last->next = NULL; queue->head = head; queue->last = last; queue->len = 0; return queue; }; void push(struct Queue *queue, int val, int depth) { struct Node *node = (struct Node *)malloc(sizeof(struct Node)); node->val = val; node->depth = depth; node->next = queue->head->next; node->pre = queue->head; node->next->pre = node; queue->head->next = node; queue->len++; } struct Node *pop(struct Queue *queue) { if (queue->len == 0) return NULL; struct Node *node = queue->head->next; node->next->pre = queue->head; queue->head->next = node->next; queue->len--; return node; } void add(struct Queue *queue, int val, int depth) { struct Node *node = (struct Node *)malloc(sizeof(struct Node)); node->val = val; node->depth = depth; node->next = queue->last; node->pre = queue->last->pre; node->pre->next = node; queue->last->pre = node; queue->len++; } void freeQueue(struct Queue *queue) { struct Node *node = queue->head; while (node != NULL) { struct Node *next = node->next; free(node); node = next; } free(queue); } // 获取相邻元素 struct Queue *getAround(int **grid, int gridSize, int *gridColSize, int point) { struct Queue *queue = initQueue(); int x = point / (*gridColSize), y = point % (*gridColSize); if (x > 0) { push(queue, (x - 1) * (*gridColSize) + y, 0); } if (x < gridSize - 1) { push(queue, (x + 1) * (*gridColSize) + y, 0); } if (y > 0) { push(queue, x * (*gridColSize) + y - 1, 0); } if (y < (*gridColSize) - 1) { push(queue, x * (*gridColSize) + y + 1, 0); } return queue; } // 标记起点岛屿 int *markSource(int **grid, int gridSize, int *gridColSize, int point) { int *marked = (int *)malloc(sizeof(int) * gridSize * (*gridColSize)); memset(marked, 0, sizeof(int) * gridSize * (*gridColSize)); struct Queue *stack = initQueue(); push(stack, point, 0); while (stack->len > 0) { struct Node *node = pop(stack); int val = node->val; marked[val] = 2; struct Queue *arounds = getAround(grid, gridSize, gridColSize, val); struct Node *aroundI = pop(arounds); while (aroundI != NULL) { int currP = aroundI->val; int currX = currP / (*gridColSize), currY = currP % (*gridColSize); if (grid[currX][currY] == 1 && marked[currP] != 2) { marked[currP] = 2; push(stack, currP, 0); } free(aroundI); aroundI = pop(arounds); } freeQueue(arounds); } freeQueue(stack); return marked; } // 标记起点与终点岛屿 int *markAll(int **grid, int gridSize, int *gridColSize) { int *marked = NULL; for (int i = 0; i < gridSize; i++) { for (int j = 0; j < *gridColSize; j++) { if (grid[i][j] == 1) { marked = markSource(grid, gridSize, gridColSize, i * (*gridColSize) + j); break; } } if (marked != NULL) break; } for (int i = 0; i < gridSize; i++) { for (int j = 0; j < *gridColSize; j++) { int point = i * (*gridColSize) + j; if (grid[i][j] == 1 && marked[point] != 2) marked[point] = 1; } } return marked; } // 由起点岛屿的所有元素开始 BFS int shortestBridge(int **grid, int gridSize, int *gridColSize) { int *marked = markAll(grid, gridSize, gridColSize); int *visit = malloc(sizeof(int) * gridSize * (*gridColSize)); memset(visit, 0, sizeof(int) * gridSize * (*gridColSize)); struct Queue *begins = initQueue(); for (int i = 0; i < gridSize; i++) { for (int j = 0; j < *gridColSize; j++) { int p = i * (*gridColSize) + j; if (marked[p] == 1) add(begins, p, 0); } } // BFS 搜索 while (begins->len > 0) { struct Node *node = pop(begins); if (marked[node->val] == 2) return node->depth - 1; struct Queue *arounds = getAround(grid, gridSize, gridColSize, node->val); while (arounds->len > 0) { struct Node *around = pop(arounds); int ap = around->val; if (marked[ap] != 1 && visit[ap] != 1) { // 已路过路径剪枝 visit[ap] = 1; add(begins, ap, node->depth + 1); } } } return -1; }
JAVA:
class Solution { public final int shortestBridge(int[][] grid) { int[][] marked = markAll(grid); Queue<Node> queue = new LinkedList<Node>(); Set<Integer> set = new HashSet<Integer>(); int xLen = grid.length, yLen = grid[0].length; for (int i = 0; i < xLen; i++) { for (int j = 0; j < yLen; j++) { if (marked[i][j] == 1) queue.add(new Node(i, j, 0)); else if (marked[i][j] == 2) set.add(i * yLen + j); } } while (queue.size() > 0) { Node node = queue.poll(); int point = node.x * yLen + node.y; if (set.contains(point)) return node.depth - 1; List<Integer> arounds = getAround(grid, node.x * yLen + node.y); for (int i = 0; i < arounds.size(); i++) { int aroundI = arounds.get(i), aroundIX = aroundI / yLen, aroundIY = aroundI % yLen; if (marked[aroundIX][aroundIY] == 1) continue; queue.add(new Node(aroundIX, aroundIY, node.depth + 1)); marked[aroundIX][aroundIY] = 1; } } return -1; } private final int[][] markAll(int[][] grid) { int xLen = grid.length, yLen = grid[0].length; int[][] markSource = null; for (int i = 0; i < xLen; i++) { if (markSource != null) break; for (int j = 0; j < yLen; j++) { if (grid[i][j] == 1) { markSource = mark(grid, i * yLen + j); break; } } } for (int i = 0; i < xLen; i++) { for (int j = 0; j < yLen; j++) { if (grid[i][j] == 1 && markSource[i][j] != 2) markSource[i][j] = 1; } } return markSource; } private final int[][] mark(int[][] grid, int point) { int xLen = grid.length, yLen = grid[0].length; int[][] marked = new int[xLen][yLen]; Stack<Integer> stack = new Stack<Integer>(); int x = point / yLen, y = point % yLen; marked[x][y] = 2; stack.push(point); while (stack.size() > 0) { int currPoint = stack.pop(); List<Integer> around = getAround(grid, currPoint); for (int i = 0; i < around.size(); i++) { int aroundI = around.get(i); int xPoint = aroundI / yLen, yPoint = aroundI % yLen; if (grid[xPoint][yPoint] == 1 && marked[xPoint][yPoint] == 0) { marked[xPoint][yPoint] = 2; stack.push(aroundI); } } } return marked; } //获取四周元素的集合 private final List<Integer> getAround(int[][] grid, int point) { List<Integer> aroundList = new ArrayList<Integer>(); int xLen = grid.length, yLen = grid[0].length; int xPoint = point / yLen, yPoint = point % yLen; if (xPoint > 0) aroundList.add((xPoint - 1) * yLen + yPoint); if (xPoint < xLen - 1) aroundList.add((xPoint + 1) * yLen + yPoint); if (yPoint > 0) aroundList.add(xPoint * yLen + yPoint - 1); if (yPoint < yLen - 1) aroundList.add(xPoint * yLen + yPoint + 1); return aroundList; } private class Node { int x; int y; int depth; Node(int x, int y, int depth) { this.x = x; this.y = y; this.depth = depth; } } }
JS:
/** * @param {number[][]} grid * @return {number} */ var shortestBridge = function (grid) { let marked = markAll(grid); let begins = [], set = new Set(); let xLen = grid.length, yLen = grid[0].length; for (let i = 0; i < xLen; i++) { for (let j = 0; j < yLen; j++) { if (marked[i][j] == 1) begins.push({val: i * yLen + j, depth: 0}); else if (marked[i][j] == 2) set.add(i * yLen + j); } } while (begins.length > 0) { let begin = begins.shift(); if (set.has(begin.val)) return parseInt(begin.depth) - 1; let arounds = getAround(grid, begin.val); for (let i = 0; i < arounds.length; i++) { let aroundP = arounds[i]; let aroundX = parseInt(aroundP / yLen), aroundY = parseInt(aroundP % yLen); if (marked[aroundX][aroundY] != 1) { marked[aroundX][aroundY] = 1; begins.push({val: aroundP, depth: parseInt(begin.depth) + 1}); } } } return null; }; var markAll = function (grid) { let xLen = grid.length, yLen = grid[0].length, marked = null; for (let i = 0; i < xLen; i++) { for (let j = 0; j < yLen; j++) { if (grid[i][j] != 0) { marked = mark(grid, i * yLen + j); break; } } if (marked) break; } for (let i = 0; i < xLen; i++) { for (let j = 0; j < yLen; j++) { if (grid[i][j] == 1 && marked[i][j] != 2) marked[i][j] = 1; } } return marked; } var mark = function (grid, point) { let xLen = grid.length, yLen = grid[0].length, x = parseInt(point / yLen), y = parseInt(point % yLen); let marked = new Array(xLen); for (let i = 0; i < xLen; i++) { marked[i] = new Array(yLen); for (let j = 0; j < yLen; j++) marked[i][j] = parseInt(0); } let stack = []; stack.push(point); marked[x][y] = 2; while (stack.length > 0) { let currP = stack.pop(); let arounds = getAround(grid, currP); for (let i = 0; i < arounds.length; i++) { let aroundP = arounds[i], aroundX = parseInt(aroundP / yLen), aroundY = parseInt(aroundP % yLen); if (grid[aroundX][aroundY] == 1 && marked[aroundX][aroundY] != 2) { marked[aroundX][aroundY] = 2; stack.push(aroundX * yLen + aroundY); } } } return marked; } var getAround = function (grid, point) { let re = []; let xLen = grid.length, yLen = grid[0].length, x = parseInt(point / yLen), y = parseInt(point % yLen); if (x > 0) re.push((x - 1) * yLen + y); if (x < xLen - 1) re.push((x + 1) * yLen + y); if (y > 0) re.push(x * yLen + y - 1); if (y < yLen - 1) re.push(x * yLen + y + 1); return re; }
当你看清人们的真相,于是你知道了,你可以忍受孤独