問題:尋找一條從左上角(a[0][0])到右下角(a[m-1][n-1])的路線,使得沿途通過的數組中的整數和最小。算法
方法一:遞歸法數組
假設到a[i-1][j]與a[i][j-1]的最短路徑和爲f(i-1,j)和f(i,j-1),那麼達到a[i][j]的路徑上全部數字的最小值爲緩存
f(i,j)=min{f(i-1,j),f(i,j-1)}+a[i][j];由此能夠採用遞歸的方法來實現,遞歸的約束條件爲遍歷到a[0][0]。在遞歸的過程當中還應該考慮到特殊的狀況:遍歷到a[i][j](i=0或j=0)的時候,智能沿着固定的路徑倒着往回找直到a[0][0].從a[m-1][n-1]逆向遞歸求解。spa
方法二:動態規劃法code
動態規劃是一種用時間來換取空間的算法,經過緩存計算的中間值,從而減小重複計算的次數,提升算法的效率。從a[0][0]正向求解。使用一個新的二維數組保存計算的中間結果。blog
package com.wyl; /** * 尋找一條從左上角(a[0][0])到右下角(a[m-1][n-1])的路線, * 使得沿途通過的數組中的整數和最小 * @author wyl * */
public class Test { /** * 使用動態規劃法,用空間換取時間的算法,將中間結果進行存儲 */
public static int minPath(Integer[][] a){ int row = a.length; int col = a[0].length; if(row == 0 && col == 0){ return -1; } Integer[][] newArray = new Integer[row][col]; //保存中間結果
newArray[0][0] = a[0][0]; for(int i=1;i<col;i++){ newArray[0][i] = newArray[0][i-1] + a[0][i]; } for(int i=1;i<row;i++){ newArray[i][0] = newArray[i-1][0] + a[i][0]; } for(int i=1;i<row;i++){ for(int j=1;j<col;j++){ if(newArray[i-1][j] < newArray[i][j-1]){ newArray[i][j] = newArray[i-1][j] + a[i][j]; System.out.println("[" + (i-1) + "," + j + "]" ); }else{ newArray[i][j] = newArray[i][j-1] + a[i][j]; System.out.println("[" + i + "," + (j-1) + "]" ); } } } System.out.println("[" + (row-1) + "," + (col-1) + "]" ); return newArray[row-1][col-1]; } public static void main(String[] args) { Integer[][] a = { {1,4,3}, {8,7,5}, {2,1,5}}; int min = minPath(a); System.out.println("最小值爲:" + min); } }