404. 左叶子之和
一个很简单的题目,我这里用dfs的遍历实现的,所以也就没有具体的遍历顺序
1 | class Solution { |
Carl的解法是标准的后序遍历方法,在了解了他的方法后我也仿写了一下
1 | class Solution { |
时间复杂度O(n),其中 n 是树中的节点个数。
空间复杂度O(n),空间复杂度和深度优先搜索使用的栈内存有关,最坏情况下,树呈链式结构,深度为O(n),对应空间复杂度为O(n)
迭代法的实现
理论上来说能用递归的题目必然涉及到了栈, 那么就可以用迭代法模拟栈的运行写出题解,由于时间关系,这里就不说了,等下一轮复习的时候再刷一遍吧,我的想法是第一遍追求广度,第二遍后面追求深度!
513. 找树左下角的值
拿到这个题第一反应是用bfs做,这种写法最简单,找到每一层第一个节点不断进行更新就可以了
bfs:
1 | class Solution { |
再贴一个我的dfs解法:
1 | class Solution { |
dfs的思路是不断地往左边找,每到最深一层就记录一下高度,最后就得到答案了
我感觉不是最优解,不太自信好像跟Carl的差不多,哈哈
112. 路径总和
这个题目的测试点好恶心,故意卡边界,开局就两个边界给我干懵了。
对于根节点为空,直接返回false
对于根节点不为空,要特判整个树是否只有这一个节点并且等于target,返回true
处理完这两步后就可以写递归代码了,这题递归代码我采用了后序遍历,观察这个题你会发现,只要找出了一组答案,最终结果就是true了,这一点跟或(||)命令很像,只要有一个表达式为true满足了,整个表达式就为true。因此这里用后序遍历
在写完上面一段后,我突然发现有一个剪枝操作,如果有一个值为true,直接进入返回就好了
1 | class Solution { |
看了Carl的代码后感觉我太菜了,-_-,他的代码把边界情况处理的太好了
1 | class Solution { |
我在写这个题目时遇到了一个问题就是把握不住tar减去val的时机,把整个过程都弄乱了,虽然最后勉强过了。。。。。
感觉没啥收获
反思
Carl的解法是先在开头特判了根节点,然后后面的代码就统一化了,就有点像是打印“1->2->3->4”这个字符串一样,先打印出“1”,后面每一步打印“->num”,这是做pat的常用套路。他这里的代码就是tar减去root->left->val,然后留在在下一层判断
我的解法就很乱了,我是在每一个结点都减去当前结点的值,然后进入递归函数进行判断,这样势必导致最后写递归出口的时候还要再减一次if(targetSum - root->val == 0)… 这么写太啰嗦了
把突然想到很重要的一点补上, 什么时候需要返回值?
Carl的说法是如果要搜索整个树,那就不要返回值。如果只是需要返回某一条路径,就需要返回值,遇到了符合条件的路径就返回。有了这个结论,以后再写递归就不会眉毛胡子一把抓了。