作者:小迅
链接:https://leetcode.cn/problems/minimum-falling-path-sum/solutions/2341965/ji-yi-hua-sou-suo-zhu-shi-chao-ji-xiang-3n58v/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
题意 -> 给定一个二维数组,返回从第一行到最后一行路径和最小值
简单直接的做法是将所有路径和都求出来,然后从所有路径和中寻找最小值返回。
使用递归即可解决上述问题,就是一个深度优先搜索过程,对于每一个位置都有三种下一步方法,每次取三种方法中最小值返回,从下往上筛选最小值,最后返回值肯定是最小值。枚举所有起始位置,取最小值即可。
int dfs(int **matrix, int n, int m, int i, int j)
{
if (j < 0 || j >= m) return INT_MAX;
if (i == n-1) return matrix[i][j];
int left = INT_MAX, mid = INT_MAX, right = INT_MAX;
left = dfs(matrix, n, m, i + 1, j - 1);
mid = dfs(matrix, n, m, i + 1, j);
right = dfs(matrix, n, m, i + 1, j + 1);
return fmin(fmin(left, mid), right) + matrix[i][j];
}
对于不同的起始位置,中间路程却存在很多相同的地方,而上述方法中对于中间重复地方还是会递归枚举,存在很多重复计算,可以使用数组对走过的路径进行记录,当下次在到当前位置时直接返回数组记录的值,上述方法就为 记忆化搜索。
代码注释超级详细
int dfs(int **matrix, int n, int m, int i, int j, int (*ans)[m])
{
if (j < 0 || j >= m) return INT_MAX;//越界无效值
if (ans[i][j] != INT_MAX) return ans[i][j];//重复路径
if (i == n-1) return matrix[i][j];//底部返回
int left = INT_MAX, mid = INT_MAX, right = INT_MAX;
left = dfs(matrix, n, m, i + 1, j - 1, ans);//左边路径
mid = dfs(matrix, n, m, i + 1, j, ans);//中间路径
right = dfs(matrix, n, m, i + 1, j + 1, ans);//右边路径
//保存当前位置路径最小值,记忆化保存
ans[i][j] = fmin(fmin(left, mid), right) + matrix[i][j];
return ans[i][j];
}
int minFallingPathSum(int** matrix, int matrixSize, int* matrixColSize){
int min = INT_MAX;
int n = matrixSize, m = matrixColSize[0];
int ans[n][m];
for (int i = 0; i < n; ++i) {//记忆化数组初始化
for (int j = 0; j < m; ++j) {
ans[i][j] = INT_MAX;
}
}
for (int i = 0; i < m; ++i) {//枚举每一个起点位置
int sum = dfs(matrix, n, m, 0, i, ans);
min = fmin(min, sum);//保存最小值路径
}
return min;
}
作者:小迅
链接:https://leetcode.cn/problems/minimum-falling-path-sum/solutions/2341965/ji-yi-hua-sou-suo-zhu-shi-chao-ji-xiang-3n58v/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。