64最小路径和

题目描述

给定一个包含非负整数的 m x n 网格,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。

说明:每次只能向下或者向右移动一步。

示例:

输入:

[[1,3,1],

[1,5,1],

[4,2,1]
]

输出: 7

解释: 因为路径 1→3→1→1→1 的总和最小。

思路分析

主体思路都是,下一个位置值=当前位置值+Math.min(往下,往右),在最下行只能往右,在最右列只能往下。

  • 暴力递归,时间通不过…
  • 动规做法。简单的动规,状态转移和base case就是上面说的情况。
  • 因为从右下角往左上角做,所以可以不用新建数组做备忘录,直接用原来的数组做备忘库,减少空间复杂度。(力扣上并没有,时间还多了2ms,小声bb)

代码实现

    /**
     * 暴力递归,时间超时
     *
     * @param grid
     * @return
     */
    public int minPathSum(int[][] grid) {
        if (grid == null) {
            return 0;
        }
        int row = grid.length;
        int col = grid[0].length;
        return process(grid, row, 0, col, 0);
    }


    public int process(int[][] grid, int row, int curRow, int col, int curCol) {
        if (curRow == row - 1 && curCol == col - 1) {
            return grid[curRow][curCol];
        }
        if (curRow == row) {
            return Integer.MAX_VALUE;
        }
        if (curCol == col) {
            return Integer.MAX_VALUE;
        }
        return grid[curRow][curCol] + Math.min(process(grid, row, curRow + 1, col, curCol),
                process(grid, row, curRow, col, curCol + 1));
    }

    /**
     * 简单动规,建立一个备忘录
     *
     * @param grid
     * @return
     */
    public int minPathSum1(int[][] grid) {
        if (grid == null) {
            return 0;
        }
        int row = grid.length - 1;
        int col = grid[0].length - 1;
        int[][] dp = new int[row + 1][col + 1];
        for (int i = row; i >= 0; i--) {
            for (int j = col; j >= 0; j--) {
                if (i == row && j != col) {
                    dp[i][j] = grid[i][j] + dp[i][j + 1];
                } else if (i != row && j == col) {
                    dp[i][j] = grid[i][j] + dp[i + 1][j];
                } else if (i != row && j != col) {
                    dp[i][j] = grid[i][j] + Math.min(dp[i + 1][j], dp[i][j + 1]);
                } else {
                    dp[i][j] = grid[i][j];
                }
            }
        }
        return dp[0][0];
    }

    /**
     * 用原本的数组作为备忘录
     * @param grid
     * @return
     */
    public int minPathSum2(int[][] grid) {
        if (grid == null) {
            return 0;
        }
        for (int i = grid.length - 1; i >= 0; i--) {
            for (int j = grid[0].length - 1; j >= 0; j--) {
                if (i == grid.length - 1 && j != grid[0].length - 1)
                    grid[i][j] = grid[i][j] + grid[i][j + 1];
                else if (j == grid[0].length - 1 && i != grid.length - 1)
                    grid[i][j] = grid[i][j] + grid[i + 1][j];
                else if (j != grid[0].length - 1 && i != grid.length - 1)
                    grid[i][j] = grid[i][j] + Math.min(grid[i + 1][j], grid[i][j + 1]);
            }
        }
        return grid[0][0];
    }
发布了117 篇原创文章 · 获赞 8 · 访问量 3690

猜你喜欢

转载自blog.csdn.net/qq_34761012/article/details/104608155