給定乙個包含非負整數的 m x n 網格,請找出一條從左上角到右下角的路徑,使得路徑上的數字總和為最小。
說明:每次只能向下或者向右移動一步。示例:
輸入:
[ [1,3,1],
[1,5,1],
[4,2,1]
]輸出: 7
解釋: 因為路徑 1→3→1→1→1 的總和最小
這是一道典型的動態規劃題
dp[i][j]表示從起點到達(i, j)位置的最小路徑和,
狀態轉移方程
dp[i][j] = math.min(dp[i - 1][j],dp[i][j-1]) + m[i][j];
邊界值dp[i][0] = dp[i-1][0] + m[i][0]
dp[0][j] = dp[0][j-1] + m[0][j]
class solution
int rlen = grid.length;
int clen = grid[0].length;
int dp = new int[rlen][clen];
// 初始化邊界值
dp[0][0] = grid[0][0];
for(int i = 1; i < rlen; i++)
for(int j = 1; j < clen; j++)
for(int i = 1; i < rlen; i++)
}return dp[rlen - 1][clen - 1];
}}
力扣測試時間為3ms, 空間為42.3mb
時間複雜度為o(n*m)
空間複雜度也是o(mn)
因為這題求的最小值,所以不能用開闢 (ows+1)*(cols+1)個空間來代替邊界初始化, 因為在在邊界處 math.min(dp[i-1][j], dp[i][j-1]) 肯定等於0, 那d[i][0]或者dp[0][j]肯定等於grid[i][j], 這是明顯錯誤的。
1 class solution
7 int rows = grid.length;
8 int cols = grid[0].length;
9 int dp = new int[rows+1][cols+1];
10 for(int i = 1; i <= rows; i++)
14 }
15 return dp[rows][cols];
16 }
17 }
但是這題求的是最大值,那麼是可以這樣做來簡化**的。
dp陣列大小等於矩陣的列的數目
狀態轉移方程
dp[j] = dp[0] + grid[i][j]; (j == 0)
dp[j] = math.min(dp[j], dp[j-1]) + grid[i][j]; (j != 0), 因為dp[j-1]在dp[j]之前就已經計算出來,已經包含了grid[i][j-1], 所以是沒有問題的。dp[j](等式左邊的dp[j])就相當於是上面的dp[i-1][j], dp[j-1]就相當於上面的dp[i][j-1],
所以dp[j] = math.min(dp[j], dp[j-1]) + grid[i][j];這時候沒問題的。
邊界值dp[j] = dp[j-1] + grid[0][j]; // 初值
1 class solution
6 int rlen = grid.length;
7 int clen = grid[0].length;
8 int dp = new int[clen];
9 // 初始化邊界值
10 dp[0] = grid[0][0];
11
12 for(int j = 1; j < clen; j++)
15 16 for(int i = 1; i < rlen; i++)else
23 }
24 }
25 return dp[clen - 1];
26 }
27 }
力扣測試時間2ms, 空間為41.9mb
時間複雜度為o(nm)
空間複雜度為o(n), n為列的數目
由於每個grid[i][j]只使用一次,所以完全可以用grid[i][j]來作為dp陣列
1 class solution
6 int rlen = grid.length;
7 int clen = grid[0].length;
8
9 // 初始化邊界值
10 for(int i = 1; i < rlen; i++)
13 for(int j = 1; j < clen; j++)
17 18 for(int i = 1; i < rlen; i++)
22 }
23 return grid[rlen - 1][clen - 1];
24 }
25 }
力扣測試時間為4ms, 空間為42.5mb
時間複雜度為o(nm)
空間複雜度為o(1)
力扣64 最小路徑和
給定乙個包含非負整數的 m x n 網格,請找出一條從左上角到右下角的路徑,使得路徑上的數字總和為最小。說明 每次只能向下或者向右移動一步。示例 輸入 1,3,1 1,5,1 4,2,1 輸出 7 解釋 因為路徑 1 3 1 1 1 的總和最小。我一開始的想法是正向思路,從起點開始,每個點都有兩種後...
64 最小路徑和 力扣(LeetCode)
給定乙個包含非負整數的 m x n 網格,請找出一條從左上角到右下角的路徑,使得路徑上的數字總和為最小。說明 每次只能向下或者向右移動一步。示例 輸入 1,3,1 1,5,1 4,2,1 輸出 7 解釋 因為路徑 1 3 1 1 1 的總和最小。同 不同路徑 一題思路相同,採用動態規劃,動態轉換方程...
64 最小路徑和
給定乙個包含非負整數的 m x n 網格,請找出一條從左上角到右下角的路徑,使得路徑上的數字總和為最小。說明 每次只能向下或者向右移動一步。示例 輸入 1,3,1 1,5,1 4,2,1 輸出 7 解釋 因為路徑 1 3 1 1 1 的總和最小。用動態規劃可直接解決,dp i j 代表著從 0 0 ...