专题二:二叉树的深度搜素(二叉树的所有路径)重点理解回溯算法的”恢复现场“
以leetcode257题为例
相信这道题大家都很容易做出来,仅仅需要一个前序遍历即可
算法原理分析
但这里我们要着重利用例题去分析回溯->"恢复现场"
我们在写dfs的时候,必然会用到回溯,用到回溯就必然有“恢复现场”
很多同学在意识到别人写回溯是因为别人利用了“恢复现场”
也就是”恢复现场“->回溯
我们要理解回溯->”恢复现场“
在前面的学习中,我们知道了全局变量的重要性
我们这里当然可以传两个全局变量,一个是字符串数组ret,每次遍历到叶子节点就是一条路径
直接存入ret即可
一个是path全局变量,用于记录路径的,比如你递归到2,那此时path:1->2->
遍历左边时,path:1->2->4(因为path是叶子结点,所以存入ret),那我们是不是要回溯到2
path:1->2->(变成这样的操作太麻烦了,包括你接着遍历到右边,又要回溯回来,path修改不方便)
此时我们发现设一个全局变量去恢复现场很困难(为什么我们还要掌握这种方法,因为在做难题时,这种方法恢复现场反而容易)
那我们此时要重新想一个方法恢复现场,那就是通过函数头的设计
为什么我没有直接引入函数头的设计???
因为这样不能很好的体会到回复现场,我们在设计全局变量path恢复现场时要删掉多余的东西才能返回,这里要着重理解恢复现场的现象/作用
函数头的设计作用就是恢复现场,帮我们删掉多余的东西,由于是传参的时候,所以我们不能很好的看到恢复现场的特性(就是每进入到新的一层我就创一个全新的path,然后接着通过传参传下去)
第一层的path和第二层的path不一样,第一层path经过处理后才传到第二层
你从第二层返回第一层依旧用的是第一层的path
所以path的删除和增加是通过函数头的设计(函数传参)完成的
总结:
全局变量的path:需要我们手动恢复现场(需要掌握,因为难题中会用到这种方法)
函数头的path:函数自动帮我们完成恢复现场 (难题不易设计函数头)
代码编写:
回溯的恢复现场在哪???
dfs(root->left,path);//这一句完之后就回溯了
而且你没有改变这一层的path,这一层的path还是原来那个path
你传进去的那个path进去之后是下一层的,你回退到这一层根本没有改变
函数自动帮我们恢复现场了
注意这里不要加&(引用)引用就类似全局变量;
这样编写就是剪枝了,先判断为不为nullptr,如果是,压根就不进去深度搜索了
就是一个剪枝操作