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;
}
posted @ 2021-05-30 23:06  牛有肉  阅读(73)  评论(0编辑  收藏  举报