代码随想录算法训练营第16天|二叉树part 04
513.找树左下角的值
题目链接:513. 找树左下角的值 - 力扣(LeetCode)
视频链接:代码随想录 (programmercarl.com)
第一想法
既然提示说迭代比递归简单一点,那就是找到到最后一层的第一个节点然后返回。那么怎么确定是最后一层呢?
每层遍历时先标记第一个节点tempNode,设置此层是否为最后一层标记flag = true。如果加入非空节点那么说明还有下层,此层就不是最后一层,flag=false。此层遍历解说后flag=true,那么就返回tempNode。
代码随想录
一直向左遍历不是二叉树的左下角,深度最大的叶子节点一定是最后一行。那么如何求得第一个节点呢?前序:中左右,中序:左中右,后序:左右中。本题没有中节点的处理逻辑,那么三种方式其实都相当于优先遍历左节点。一旦得到了深度最大得叶子节点,那么它一定是最靠近左侧的。
最靠左侧的值未必就是左孩子,只要优先遍历左侧就可以。
如果是层序遍历则不用很麻烦,每层遍历记录第一个节点。所有层遍历完后直接返回这个记录值即可。它一定是最后一层得第一个节点。
代码
class Solution { public int findBottomLeftValue(TreeNode root) { Deque deque = new LinkedList(); deque.offer(root); int result = 0; while (!deque.isEmpty()){ int size = deque.size(); for (int i = 0; i maxDepth){ maxDepth = depth; result = root.val; } return; } //优先遍历左节点 if(root.left!=null){ depth++; traversal(root.left,depth); depth--;//回溯,深度-1 } //再遍历右节点 if(root.right!=null){ depth++; traversal(root.right,depth); depth--; } //中间节点是不做处理的。 } }
路径总和
题目链接:112. 路径总和 - 力扣(LeetCode) 113. 路径总和 II - 力扣(LeetCode)
文档/视频链接:代码随想录 (programmercarl.com)
代码随想录
返回值是Boolean,在这颗二叉树里只需要找到一条路径符合返回直接返回就可以,没有必要遍历所有的节点。所以一旦到叶子节点发现符合要求后,就一路将true返回直至根节点。
参数:计数器 count,TreeNode node
正向思考是:传入0,每遇到一个节点,就加val,看看是不是与target相等。
反向思考:更简单一些,这里直接传入目标值。遇到一个节点就减val。如果到叶子节点,该数值减为0,那么沿此路的所有节点相加恰好等于target。
终止条件:叶子节点并且count为0,return true。
叶子节点但count不为0,return false。
单层递归逻辑:
以上没有对root做判空。
若左不为空:count减左节点的值,递归遍历左孩子。如果左孩子遍历返回来的值是true,则左方向有符合题目要求的路径,那么就应该将这个true结果继续向上返回。回溯将左方向的值加回来。
若右不为空:
如果都没有返回true,那么最终返回false
代码
//LeetCode112 class Solution { public boolean hasPathSum(TreeNode root, int targetSum) { if(root==null)return false; targetSum -= root.val; if(root.left==null&&root.right==null)return targetSum==0; if(root.left!=null){ if(hasPathSum(root.left,targetSum)) return true; } if(root.right!=null){ if (hasPathSum(root.right,targetSum))return true; } return false; } }
LeetCode113,自己写的有错误,还没找出来原因。
class Solution { List result; LinkedList path; public List pathSum (TreeNode root,int targetSum) { result = new LinkedList(); path = new LinkedList(); travesal(root, targetSum); return result; } private void travesal(TreeNode root, int count) { if (root == null) return; path.offer(root.val); count -= root.val; if (root.left == null && root.right == null && count == 0) { result.add(new LinkedList(path)); } travesal(root.left, count); travesal(root.right, count); path.removeLast(); // 回溯 } }
106.从中序与后序遍历序列构造二叉树
题目链接:106. 从中序与后序遍历序列构造二叉树 - 力扣(LeetCode)
文档/视频链接:代码随想录 (programmercarl.com)
代码随想录想法
框架:
-
第一步:如果数组大小为零的话,说明是空节点了。
-
第二步:如果不为空,那么取后序数组最后一个元素作为节点元素。
-
第三步:找到后序数组最后一个元素在中序数组的位置,作为切割点
-
第四步:切割中序数组,切成中序左数组和中序右数组 (顺序别搞反了,一定是先切中序数组)
-
第五步:切割后序数组,切成后序左数组和后序右数组
-
第六步:递归处理左区间和右区间
class Solution { public TreeNode buildTree(int[] inorder, int[] postorder) { if(inorder.length==0||postorder.length==0) return null; return buildHelper(inorder,0,inorder.length,postorder,0,postorder.length); } public TreeNode buildHelper(int[] inorder, int inorderStart, int inorderEnd, int[] postorder, int postorderStart, int postorderEnd) { if(postorderStart==postorderEnd)return null; int rootValue = postorder[postorderEnd - 1]; TreeNode root = new TreeNode(rootValue); int middleIndex; for(middleIndex = inorderStart;middleIndex