动态规划 07

80 阅读1分钟

LeetCode 64

leetcode-cn.com/problems/mi…

解题思路

本题为典型的动态规划

第一步:构造 二维dp

从左上角走到右下角,不走回头路,所以只能走下和右

设置二维dp,其值含义:走到当前位置所需要的的最小路径和

dp[i][j] = min(dp[i][j-1], dp[i-1][j]) + grid[i][j];

初始化:

(i == 0) dp[0][j] = dp[0][j-1] + grid[i][j], 0 <= j < col
(j == 0) dp[i][0] = dp[i-1][j] + grid[i][j], 0 <= i < row

public int minPathSum(int[][] grid) {
	if (grid == null || grid.length == 0 || grid[0].length == 0) {
		return 0;
	}

	int row = grid.length, col = grid[0].length;
	int[][] dp = new int[row][col];
	dp[0][0] = grid[0][0];
	for (int i = 1; i < row; i++) {
		dp[i][0] = dp[i - 1][0] + grid[i][0];
	}
	for (int j = 1; j < col; j++) {
		dp[0][j] = dp[0][j - 1] + grid[0][j];
	}
	for (int i = 1; i < row; i++) {
		for (int j = 1; j < col; j++) {
			dp[i][j] = Math.min(dp[i - 1][j], dp[i][j - 1]) + grid[i][j];
		}
	}
	return dp[row - 1][col - 1];
}

第二步:压缩状态 实现一维dp

利用滚动数组将第一维删掉,保留第二维

  1. 从第一行开始
    当前位置只能从边走过来 dp[j] = dp[j-1] + grid[0][j],0 <= j <= col

  2. 第二行及以后

(1) j == 0,只能从上面走下来。
dp[0] += grid[i][j]

(2) 1 <= j < col,从上或左走到当前位置
dp[j] = min(dp[j-1], dp[j]) + grid[i][j]
dp[j-1]是左边的,dp[j]是上边的

public int minPathSum(int[][] grid) {
	if (grid == null || grid.length == 0 || grid[0].length == 0) {
		return 0;
	}
	
	int row = grid.length, col = grid[0].length;
	int[] dp = new int[col];
	dp[0] = grid[0][0];
	for (int j = 1; j < col; j++) {
		dp[j] = dp[j - 1] + grid[0][j];
	}
	for (int i = 1; i < row; i++) {
		for (int j = 0; j < col; j++) {
			if (j == 0) {
				dp[j] += grid[i][j];
			} else {
				dp[j] = Math.min(dp[j - 1], dp[j]) + grid[i][j];
			}
		}
	}
	return dp[col - 1];
}