我正在经历this leetcode problem for going from top left to bottom right.
有多少个可能的唯一路径?
通过存储每个索引的结果,我能够理解这种动态编程方法。
public int uniquePaths(int m, int n) {
int count[][] = new int[m][n];
for (int i = 0; i < m; i++)
count[i][0] = 1;
for (int j = 0; j < n; j++)
count[0][j] = 1;
for (int i = 1; i < m; i++) {
for (int j = 1; j < n; j++) {
count[i][j] = count[i-1][j] + count[i][j-1]; //+ count[i-1][j-1];
}
}
return count[m-1][n-1];
// if (m == 1 || n == 1) return 1;
// return uniquePaths(m-1, n) + uniquePaths(m, n-1);
}
但是,我找到了我无法理解的解决方案。
public int uniquePaths(int m, int n) {
int[] dp = new int[n];
dp[0] = 1;
for (int i = 0; i < m; i++) {
for (int j = 1; j < n; j++) {
dp[j] += dp[j - 1];
}
}
return dp[n - 1];
}
请有人解释第二种解决方案。
答案 0 :(得分:2)
在第一个解决方案中,整个矩阵都被填充,但是您会注意到在count[i][j] = count[i-1][j] + count[i][j-1]
中每行仅使用一次。
因此,您基本上可以在使用后将其丢弃。第二个解决方案就是这样做。我们只能使用一行来执行所有计算。
填入代码后,我们可以将代码替换为count[0][j] = count[0][j] + count[0][j-1]
,基本上就是count[0][j] += count[0][j-1]
。
请注意
for (int i = 0; i < m; i++)
count[i][0] = 1;
没用,我们总是覆盖那些单元格。
还有
for (int j = 0; j < n; j++)
count[0][j] = 1;
等效于
dp[0][0] = 1;
for (int j = 1; j < n; j++) {
dp[0][j] += dp[0][j - 1];
}
在第二个示例中我们已经将其作为内部循环。
答案 1 :(得分:1)
基本上,在第二个解决方案中,我们通过利用用于保存上一行计算的空间来优化空间复杂度。因为在计算当前行中的值之后,它在jth
位置的值将仅被下一行jth
位置的值消耗。
因此,dp[j] += dp[j - 1];
=> dp[j] = dp[j] + dp[j - 1]
=> dp value of jth column of current row = dp value at jth pos in prev row + dp value of j-1 th pos of current row
此处,前一行的值jth
列被当前行的jth
位置的值覆盖。
谢谢!