標籤:去掉 minimum [] 代碼 nat sum Plan 遇到 重複
Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right which minimizes the sum of all numbers along its path.
Note: You can only move either down or right at any point in time.
Example:
Input:[ [1,3,1], [1,5,1], [4,2,1]]Output: 7Explanation: Because the path 1→3→1→1→1 minimizes the sum.
分析:題目意思也很簡單,從左上方到右下角,只能往右和下走,要求從找一條路使得路徑上和最小。很明顯使用動態規劃來求解,下面就來做動態規劃三要素:1、dp[i][j]代表走到[i][j]位置路徑和最小的和2、邊界條件初始化:dp[0][0] = grid[0][0]dp[0][j] = dp[0][j-1] + grid[0][j]dp[i][0] = dp[i-1][0] + grid[i][0]3、狀態轉移方程:可以這麼考慮,因為只能向右向下,因此到第[i][j]位置只能有兩條路,只要找到這兩個路最小的那個就可以了。dp[i][j] = min(dp[i][j-1],dp[i-1][j]) + grid[i][j]所以代碼如下:
1 class Solution { 2 public int minPathSum(int[][] grid) { 3 int M = grid.length; 4 int N = grid[0].length; 5 int[][] dp = new int[M][N]; 6 7 dp[0][0] = grid[0][0]; 8 for ( int j = 1 ; j < N ; j ++ ) dp[0][j] = dp[0][j-1] + grid[0][j]; 9 for ( int i = 1 ; i < M ; i ++ ) dp[i][0] = dp[i-1][0] + grid[i][0];10 11 for ( int i = 1 ; i < M ; i ++ ){12 for ( int j = 1 ; j < N ; j ++ ){13 dp[i][j] = Math.min(dp[i-1][j],dp[i][j-1]) + grid[i][j];14 }15 }16 return dp[M-1][N-1];17 18 }19 }
已耗用時間6ms。
這個題目還是比較簡單的,之前面試滴滴也遇到過。上次面試接著又問了一個有深度的問題:現在問題變成從左上方到右下角再回到左上方,要求找這個閉環的路徑和最小值,要求不能有重複。
比如上面的例題,最後應該是找到1→3→1→1→1→2→4→1→1。
正確的思路:正確的理解,相當於從左上方到右下角,找兩個路徑,這兩個路徑和是最小和次小。因此使用四維dp,(i,j)(p,q),每一個狀態轉移的時候都有四個參數要更新。(i,j)用來記錄最小的路徑,(p,q)用來記錄次小的路徑,這裡要注意找次小的時候要去掉最小的路徑。
四維dp是非常麻煩的,下面如何簡化,也就是降維呢?這裡注意到(i,j)(p,q)的關係:i+j==p+q。有了這個關係,就可以把四維dp降到三維dp,相對就比較好做了。
面試應該說出思路就好了,代碼還是太繁瑣了。。。
[leetcode] Minimum Path Sum