问题
给定m x n网格填充非负数,找到从左上角到右下角的路径,最大化沿其路径的所有数字的总和。
注意:您只能在任何时间点向下或向右移动。
方法
我只是通过天真的递归来接近这个,我为此写的代码如下所示。 我遇到的问题是我无法弄清楚如何恢复网格中的路径。我通过引用(路径)传递了一个向量,所以我可以恢复每个递归调用的路径。
int getMaxPath(vector<vector<int> > Grid, int r, int c, vector<int> &path)
{
if((r > Grid.size()-1) || (c > Grid[0].size()-1))
return 0;
if(r==Grid.size()-1 && c==Grid[0].size()-1){
return Grid[r][c];
}
int rs = getMaxPath(Grid, r, c+1, path);
int ds = getMaxPath(Grid, r+1, c, path);
(rs > ds) ? path.push_back(Grid[r][c+1]) ? path.push_back(Grid[r+1][c]); // Recover path here.
return max(rs,ds)+Grid[r][c];
}
正如我们所看到的,代码的主要部分是递归,我将这条线路恢复原样(评论) -
{{1}}
但是我在某个地方错过了这一点,因为当从递归调用中卷绕和展开时,这会导致当前元素的多个副本进入路径。
我做错了什么?
答案 0 :(得分:1)
由于图形被编码为矩阵,因此每个顶点应该是一对,即public class Foo<T extends Base> implements Bar<T> {
private Bar<T> wrapped;
public void setWrapped(Bar<? extends Base> input) {
wrapped = input;
}
}
,表示顶点的std::pair<int, int>
。
因此,path参数应声明为(row, column)
vector<pair<int, int>>& path
修改强>
该方法仍然不正确,因为每个递归调用(包括未选择的那些(最佳))仍会将其结果放在路径中。我们需要向每个递归调用传递一个单独的向量,如果选中它,则只将它附加到我们的传递:
int getMaxPath(vector<vector<int> > Grid, int r, int c, vector<pair<int, int>>& path)
{
...
(rs > ds) ? path.emplace_back(r, c+1) : path.emplace_back(r+1, c);
}
p.s。:如果如你所说,你想要捕获矩阵权重而不是坐标,你可以调整它,但遵循相同的逻辑以避免重复。
<强>测试强>
int getMaxPath(vector<vector<int> > Grid, int r, int c, vector<pair<int, int >> &path)
{
if ((r > Grid.size() - 1) || (c > Grid[0].size() - 1))
return 0;
path.emplace_back(r, c);
if (r == Grid.size() - 1 && c == Grid[0].size() - 1)
return Grid[r][c];
vector<pair<int, int >> rsPath, dsPath;
int rs = getMaxPath(Grid, r, c + 1, rsPath);
int ds = getMaxPath(Grid, r + 1, c, dsPath);
if (rs > ds) {
path.insert(path.end(), rsPath.begin(), rsPath.end());
return rs + Grid[r][c];
}
else {
path.insert(path.end(), dsPath.begin(), dsPath.end());
return ds + Grid[r][c];
}
}
<强>输出强>
(0,0)(1,0)(1,1)(1,2)(2,2)(2,3)(3,3)