從物理學到計算機,再到硬件,再到人工智能!
藍橋杯備賽 (LintCode上刷的第八題)
問題描述
給定一個只含非負整數的m*n網格,找到一條從左上角到右下角的可以使數字和最小的路徑。
你在同一時間只能向下或者向右移動一步!
問題分析
是一個典型的最短路徑問題,思想都是一樣的。此次代碼參考了《程序員代碼面試指南 IT名企算法與數據結構題目最優解》這本書,所以是很優化的代碼。採用一維數組記錄從起點到當前點的最短路徑。並且當行與列不相等時,選擇行數或者列數較少的建立數組。具體見代碼,代碼註釋超級詳細!
JAVA實現代碼
package DP;
public class minPath110_1111 {
/**
* 計算從左上角到右下角的最短路徑:
* 1.採用一維數組進行記錄從起點到當前點的最短距離
* 2.如果行數和列數不相等,選擇行數或列數較小的建立輔助矩陣
* @param arr 路徑數組
* @return
*/
public int minPath(int[][] arr) {
if (arr == null || arr.length == 0 || arr[0] == null || arr[0].length == 0) {
return 0;
}
//行數與列數較大的那個爲more
int more = Math.max(arr.length, arr[0].length);
//行數與列數較小的那個爲less
int less = Math.min(arr.length, arr[0].length);
//行數是不是大於等於列數
boolean rowmore = more == arr.length;
//輔助數組的長度僅爲行數與列數中的最小值,help[i]表示從起點到該點的最短距離
int[] help = new int[less];
//賦初值
help[0] = arr[0][0];
for (int i = 1; i < less; i ++) {
//help的初值爲arr數組行數或列數較小的第一行或第一列相加的值
help[i] = help[i - 1] + (rowmore ? arr[0][i] : arr[i][0]);
}
for (int i = 1; i < more; i ++) {
//arr數組中的第一行或第一列的數據需要單獨處理,需要隨着行數或者列數的增加滾動更新
help[0] = help[0] + (rowmore ? arr[i][0] : arr[0][i]);
//遍歷行數或列數較少的每一行或每一列數據
for (int j = 1; j < less; j ++) {
//選擇到達該點的兩種路徑中最短的路徑,再加上當前的值,則更新help對應數組的值
help[j] = Math.min(help[j - 1], help[j]) + (rowmore ? arr[i][j] : arr[j][i]);
}
}
return help[less - 1];
}
}