代码随想录算法训练营第十八天[二刷]|513.找树左下角的值. 112. 路径总和 105,106 构造树

513.找树左下角的值

层序遍历 + 找到最后一行的第一个值
思路: 确定一个变量res 不停地把每一层的第一个值*放到变量里,这样最后一个一定是最后一行的数值。
*:很小的地方需要注意,因为size是作为他是否进入循环的标准 ,他会在每一次poll之后减1,所以如果用的while循环还需要用另外一个变量保存这个size 作为判定该node是否是第一个

112. 路径总和

这个题目和昨天的记录路径很像。
首先递归三部曲:

  1. 判定停止条件: 本身为null的时候 说明走到了子节点下面,但是还没找到符合条件的路径,返回false即可. 如果只有一个节点,这样root.left/ right 就为空,单独拿出来判定(判定是否为0)
  2. 单层判定逻辑: 如果走到了最后的节点,就可以进行停止的判定:减去自身的值,看是否等于0.
  3. 向下递归:这里有一个回溯的需求:因为之后右子树还需要该值,所以递归返回回来之后,要把减去的值再加回来。至于什么时候需要回溯,把卡哥小助手的原话贴在这里,觉得说的很直观,也很有用,自己要多多练习才能更实际的掌握这句话!
    用不用回溯 取决于修改后的变量传入下一层函数后 本层函数还需不需要它了 是需要它改变后的值还是原值 一般要原值就回溯 要修改后的值通过定义函数返回值来得到
    对于我自己来说,回溯有点像 rollback的感觉, 回到上一层把处理好的数据再改回来。再开始探索新的路线。 具体到代码就是
....前面的处理逻辑
//如果把回溯的过程写出来
if (root.left != null){  
//进入下一层的时候 减去了自身的数值
        targetSum -= root.val;    
        boolean check = hasPathSum(root.left, targetSum);
        if (check) return true;
      //之后右子树还要用所以要把数值在进去,然后再在右子树逻辑中剪掉
        targetSum += root.val;

    }
//简略版如下:可以看到进入到左边的值。 和右边的值是一样的。间接的完成了递归
        boolean leftRes = hasPathSum(root.left, targetSum - root.val);
        boolean rightRes = hasPathSum(root.right, targetSum - root.val);

105: 从前序与中序遍历序列构造二叉树
根据遍历性质, preorder 的数组是中 左 右。第一个一定是 root, 并且后面的一定跟着的是左子树的root,
eg:
preorder = [3,9,20,15,7],
inorder = [9,3,15,20,7]
第一次遍历,3 一定是整个树的根节点。通过这个在中序中找到左右子树的范围找到范围之后,分别进行左右子树的递归。这样再次调用的时候,index 会继续往下一个到9,而这个9也是左子树的下一个root以此类推。

递归调用三要素:

  1. 停止条件: 因为是一直再不停的切割找root。有些像二分的判定, 如果找到 Ind已经不合理了 即无法构成区间(StartInd >= EndIndex)左闭右开所以有等于。
  2. 单层递归: 一个个找root, 定义为root节点,左递归,右递归
  3. 最后返回一开始的root节点即可

优化成为O(N): 对Preorder 的值去Inorder 找index,可以用一个map 记录,就避免了每次都要重新弄去Inorder 的数组里找Index

简化输入参数版本:
Inorder 的起始和截止都需要 这没有办法,因为每次都要找rootInd,他就是左子树的截止,右子树的开始,所以一定需要作为参数输入。
preorder 中只用到了StartInd, 并且他是一直递增的,所以可以直接在每次递归里递增,就不用作为参数的输入了,否则的话,记得在left 子树中 +1 right 子树中是需要加左子树的Length而不是也加1,( 虽然很简单的错误但是我还是犯了,哈哈)

106.从中序与后序遍历序列构造二叉树
可以说和105十分相似了,只不过这里是从最后一个往前遍历,找root.
通过这两个,大概总结一下:
中序遍历的目的是通过另外一个数组找到的root, 知道左右的值
另外一个序 的目的是为了找root

Debug 树结构的小技巧:
在递归函数里第一行就打印输入值(防止return null 的那个截止层没来得及打出来),看每一个有没有输入参数就错误的问题。
知道每一行打印出来的是对应的哪一层哪一边的树,可以在草稿纸上画出你所建立的树对应的位置打印的值

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值