110. 最小路徑和

從物理學到計算機,再到硬件,再到人工智能!
藍橋杯備賽 (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];
	}
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章