Minimum-Path-Sum——最小路径和

题目描述:

给定一个只含非负整数的m*n网格,找到一条从左上角到右下角的可以使数字和最小的路径。

 

样例 1:

输入:  [[1,3,1],[1,5,1],[4,2,1]]
输出: 7	
样例解释:
路线为: 1 -> 3 -> 1 -> 1 -> 1。

样例 2:

输入:  [[1,3,2]]
输出:  6
解释:  
路线是: 1 -> 3 -> 2

Notice

你在同一时间只能向下或者向右移动一步

 

AC代码:

 1 public class Solution {
 2 
 3     /**
 4      * @param grid: a list of lists of integers
 5      * @return: An integer, minimizes the sum of all numbers along its path
 6      */
 7     public int minPathSum(int[][] grid) {
 8         // write your code here
 9         if (grid == null || grid.length == 0 || grid[0].length == 0) {
10             return 0;
11         }
12 
13         int m = grid.length;
14         int n = grid[0].length;
15 
16         // 坐标型动态规划
17         // 最后一步:每个点的路径之和只可能来自上面和左边
18         int[][] dp = new int[2][n]; // 代表(0, 0)到(i, j)的数字和最小的路径
19 
20         // 时间复杂度:O(mn) 空间复杂度:O(mn)
21         // 为了降低空间复杂度,这里可以采用滚动数组
22 
23         int now = 0, old = 1;
24         int top;
25         int left;
26         // 转移方程
27         for (int i = 0; i < m; i++) {
28             // 这里是滚动数组的最容易忽视的一点:考虑完一行之后才能滚动,不然会出错
29             // 更新
30             old = now;
31             now = 1 - now;
32             for ( int j = 0; j < n; j++) {
33                 // 左上角的点
34                 if (i == 0 && j == 0) {
35                     // 初始化
36                     dp[now][0] = grid[0][0];
37                     continue;
38                 }
39                 dp[now][j] = grid[i][j];
40                 // 判断上面是否有点
41                 if (i > 0) {
42                     // 上面有点
43                     top = dp[old][j];
44                 } else {
45                     // 这里设置为无穷大,是为了后面比较,因为是选最小的,反之如果选最大,这里
46                     // 可以设置为无穷小
47                     top = Integer.MAX_VALUE;
48                 }
49 
50                 // 同理判断左边点是否存在
51                 if (j > 0) {
52                     left = dp[now][j - 1];
53                 } else {
54                     left = Integer.MAX_VALUE;
55                 }
56 
57                 // 比较上面点和左边点的值哪个更小,最后不要忘了加上当前点的值
58                 if (top < left) {
59                     dp[now][j] += top;
60                 } else {
61                     dp[now][j] += left;
62                 }
63             }
64         }
65 
66         return dp[now][n - 1];
67     }
68 }

 

posted @ 2021-03-27 15:29  没有你哪有我  阅读(86)  评论(0编辑  收藏  举报