什么时候需要回溯?
通过最近的做题,有了一个新的理解,什么时候回溯,回溯谁?
如果这是一个带入dfs的参数,那么他就不需要回溯,dfs就是一种做选择,二叉树上搜索也是一种做选择,分别是左子树,右子树都是一种选择。选择改变的,如果并不是参数,而是全局变量,那就需要撤销这次选择带来的影响。 就需要回溯对于这个全局变量的改变的状态
当从上一层的状态变为下一层的状态有多种可能的时候,
不同种的可能可能是不同的答案,由上一层的状态变为下一层的状态,需要回溯到上一层的状态再变为下一层状态的另一种情况
这时候就需要回溯
枚举过程中,去尝试
回溯的位置,要把这一层的状态都尝试完,再回溯到上一个状态,以上一个状态去尝试另一种方法
https://www.acwing.com/problem/content/description/45/
简单的例题
cur += val;
path.add(val);
if(cur == target && root.left == null && root.right == null)
res.add(new ArrayList<>(path));
dfs(root.left, cur);
dfs(root.right, cur);
cur -= val;
path.remove(path.size() - 1);
要在分别遍历完左右子树,再回溯到上一个状态,也就是另一个分支
//暂时的理解,有深入理解再更新
DFS
什么时候 DFS要返回一个值,
例如361,dfs
这个题就是DFS,并不休要回溯,因为是遍历二叉树,并不是求方案个数,求排列组合那种需要判断不同分支
会带来不一样的结果, 所以这个仅仅是DFS 搜索
什么时候DFS需要返回值,什么void,个人目前的理解,就是如果DFS到底了,
要对原来的进行变化, 会产生一个新的状态,那么就要return一个值
例如361 题, 当搜索到叶节点时候,要删除叶节点,这里就让叶节点返回null, 就生成了一颗新的树
- Maximum Path Quality of a Graph
这也是一道暴搜问题
文章开头说的一段对于回溯的理解,有一点模糊的地方,这道题就很好的表示了这点
for(int[] t : graph.getOrDefault(start, new ArrayList<>())){
int nextNode = t[0];
int time = t[1];
//curTime += time;
dfs(nextNode, curTime + time, curValue);
//curTime -= time;
}
如果先将curTime += time, 再把curTime代入下一层,那就要回溯,因为相当于在这一层的时候改变了状态,那就要回溯到原来的状态,如果是直接dfs curTime + time,那就不需要回溯了,因为对于curTime来说,你并没有改变他
加油
共同加油!!!