LeetCode64題:最小路徑和
阿新 • • 發佈:2018-12-26
思路:
題目要求的是從左上角即[0,0]位置開始,到右下角即[m-1,n-1]位置為止的最小路徑和。倒過來思考的話,對於右下角[m-1,n-1]來說,它的上一步只有兩個位置即[m-2,n-1]和[m-1,n-2],因此問題就可以轉化為求從[0,0]到這兩個位置的路徑和的較小值,即狀態轉移公式為:min ( arr[m-1][n-1] ) = min ( arr[m-1][n-1]+min( arr[m-2][n-1] ),arr[m-1][n-1]+min( arr[m-1][n-2] )),因此可以很容易的用遞迴方式求解。
解法一:遞迴法
public int minPathSum(int[][] grid) { return help1(grid,grid.length-1,grid[0].length-1); } public int help1(int[][] arr,int row,int col){ if(row == 0 && col == 0){ return arr[row][col]; } if(row != 0 && col == 0){ return arr[row][col]+help1(arr,row-1,col); } if(row == 0 && col != 0){ return arr[row][col]+help1(arr,row,col-1); } return arr[row][col]+Math.min(help1(arr,row-1,col),help1(arr,row,col-1)); }
但是遞迴法涉及到很多的重複計算,時間複雜度超時,因此需要換一種思路。剛才採用遞迴法時,考慮的是從後往前求解,那麼現在反過來,從前往後可不可以呢?如果能從前往後計算的話,那麼就可以依次求出從左上角到任意一個位置的最小路徑和了,因為要求的這個位置之前的兩個位置的最小值已經知道了,這樣就不存在重複計算(即動態規劃法)。那麼這種思路能不能實現呢?接著思考,對於二維陣列來說,在邊界上的位置,它的上一步只有一個,而處在中間位置的才有兩個。而對二維陣列進行遍歷的時候,就是從上到下從左到右的遍歷的,跟路徑的行走規則一致,那麼就可以在遍歷的時候直接求出每個位置的最小路徑和了。
解法二:動態規劃法
public int minPathSum(int[][] grid) { return help(grid); } public int help(int[][] arr){ int row = arr.length; int col = arr[0].length; for(int i=0;i<row;i++){ for(int j=0;j<col;j++){ if(i == 0 && j == 0){ continue; } if(i != 0 && j != 0){ arr[i][j] += Math.min(arr[i-1][j], arr[i][j-1]); }else if(i == 0){ arr[i][j] += arr[i][j-1]; }else{ arr[i][j] += arr[i-1][j]; } } } return arr[row-1][col-1]; }