Leetcode 1706 球会落在何处 记忆化
JAVA 暴力(BFS):
public final int[] findBall(int[][] grid) { int len = grid[0].length; int[] balls = new int[len]; for (int i = 0; i < balls.length; i++) balls[i] = i; for (int i = 0; i < grid.length; i++) { for (int j = 0; j < balls.length; j++) balls[j] = next(balls[j], grid[i]); } return balls; } private final int next(int position, int[] row) { if (position == -1) return -1; if (position == 0 && row[0] == -1) return -1; int right = row.length - 1; if (position == right && row[right] == 1) return -1; if (row[position] == 1 && row[position + 1] == -1) return -1; if (row[position] == -1 && row[position - 1] == 1) return -1; return row[position] == 1 ? position + 1 : position - 1; }
时间复杂度与空间复杂度均为 N2 。计算中存在非常多的重复计算,因为从同一个格子下落时,最终到达的格子也是相同的。因此可以通过 DFS 并进行记忆化来优化重复计算。
JAVA 记忆化递归:
public final int[] findBall(int[][] grid) { int[] balls = new int[grid[0].length]; int[][] cache = new int[grid.length][grid[0].length]; for (int i = 0; i < balls.length; i++) balls[i] = dfs(grid, 0, i, cache); return balls; } private final int dfs(int[][] grid, int row, int cell, int[][] cache) { if (row == grid.length) return cell; if (cache[row][cell] != 0) return cache[row][cell]; int re = 0, len = grid[0].length, right = len - 1; if (cell == 0 && grid[row][0] == -1) re = -1; else if (cell == right && grid[row][right] == 1) re = -1; else if (grid[row][cell] == 1 && grid[row][cell + 1] == -1) re = -1; else if (grid[row][cell] == -1 && grid[row][cell - 1] == 1) re = -1; else re = dfs(grid, row + 1, grid[row][cell] == 1 ? cell + 1 : cell - 1, cache); cache[row][cell] = re; return re; }
与 BFS 相比,效果明显:
JS 记忆化:
/** * @param {number[][]} grid * @return {number[]} */ var findBall = function (grid) { let row = grid.length, cell = grid[0].length; let balls = new Array(cell).fill(0), cache = new Array(row); for (let i = 0; i < row; i++) cache[i] = new Array(cell).fill(0); for (let i = 0; i < cell; i++) balls[i] = dfs(grid, 0, i, cache); return balls; }; var dfs = function (grid, row, cell, cache) { if (row == grid.length) return cell; if (cache[row][cell]) return cache[row][cell]; let re = 0, right = grid[0].length - 1; if (cell == 0 && grid[row][0] == -1) re = -1; else if (cell == right && grid[row][right] == 1) re = -1; else if (grid[row][cell] == 1 && grid[row][cell + 1] == -1) re = -1; else if (grid[row][cell - 1] == 1 && grid[row][cell] == -1) re = -1; else re = dfs(grid, row + 1, grid[row][cell] == 1 ? cell + 1 : cell - 1, cache); cache[row][cell] = re; return re; }
当你看清人们的真相,于是你知道了,你可以忍受孤独