leetcode-zgd-day18-513.找树左下角的值/112.113路径总和 i.ii/106.105.从中序与后序/前序遍历序列构造二叉树

80 阅读1分钟

513.找树左下角的值

题目链接:513. 找树左下角的值 - 力扣(LeetCode)

迭代法:借助队列进行层序遍历

 class Solution {
     public int findBottomLeftValue(TreeNode root) {
         // 层序遍历-迭代
         int ans = -1;
         if(root == null) return -1;
         Queue<TreeNode> que = new LinkedList<>();
         que.offer(root);
         while(!que.isEmpty()){
             int size = que.size();
             for(int i = 0; i < size; i++){
                 TreeNode cur = que.poll();
                 if(i == 0) ans = cur.val;
                 if(cur.left != null) que.offer(cur.left);
                 if(cur.right != null) que.offer(cur.right);
             }
         }
         return ans;
     }
 }

112.路径总和

题目链接:112. 路径总和 - 力扣(LeetCode)

回溯法求解,需要注意的是,下面的代码中当进入节点之前就已经把要进入节点的值加上了

 class Solution {
 ​
     boolean flag = false;
 ​
     public boolean hasPathSum(TreeNode root, int targetSum) {
         if(root == null) return false;
         hasTargetSum(root, targetSum, root.val);
         return flag;
     }
     public void hasTargetSum(TreeNode root, int targetSum, int sum){
         if(root.left == null && root.right == null && sum == targetSum) flag = true; // 终止条件
         if(root.left == null && root.right == null) return;
         if(root.left != null){
             hasTargetSum(root.left, targetSum, sum + root.left.val);
         }
         if(root.right != null){
             hasTargetSum(root.right, targetSum, sum + root.right.val);
         }
     }
 }

113.路径总和ii

题目链接:113. 路径总和 II - 力扣(LeetCode)

和上题是一样采用回溯法的思路求解,需要注意的是,下面的代码中当进入节点之前就已经把要进入节点的值加上了

 class Solution {
     public List<List<Integer>> pathSum(TreeNode root, int targetSum) {
         List<List<Integer>> ans = new ArrayList<>();
         if(root == null) return ans;
         List<Integer> path = new ArrayList<>();
         path.add(root.val);
         findPath(root, targetSum, root.val, path, ans);
         return ans;
     }
     void findPath(TreeNode root, int targetSum, int sum, List<Integer> path, List<List<Integer>> ans){
         // 回溯的终止条件
         if(root.left == null && root.right == null){ // 叶子节点
             if(sum == targetSum) ans.add(new ArrayList<>(path)); // 符合条件的路径
             return;
         }
         if(root.left != null){
             path.add(root.left.val);
             findPath(root.left,targetSum,sum + root.left.val, path, ans);
             path.remove(path.size() - 1);
         }
         if(root.right != null){
             path.add(root.right.val);
             findPath(root.right,targetSum,sum + root.right.val, path, ans);
             path.remove(path.size() - 1);
         }
 ​
     }
 }

106.从中序与后序遍历序列构造二叉树

题目链接:106. 从中序与后序遍历序列构造二叉树 - 力扣(LeetCode)

首先通过一个map记录中序数组中元素和其对应的下标,然后递归获取后序数组的最后一个元素,通过前面的map确定这个元素在中序数组中的位置,然后根据这个位置,我们就可以对中序序列和后序序列进行分割。

分割后的就变成了两段子数组,继续迭代进行如下操作。该方法的返回值是一个树节点,并且分割后的子数组的迭代结果就是这个树节点的左右孩子。通过迭代就可以将整个树的关联关系创建出来。二叉树也就构造完成了。105题同理

 class Solution {
 ​
     Map<Integer,Integer> map;
 ​
     public TreeNode buildTree(int[] inorder, int[] postorder) {
         map = new HashMap<>();
         for(int i = 0; i < inorder.length; i++){
             map.put(inorder[i], i);
         }
         return findNode(inorder, 0, inorder.length, postorder, 0, postorder.length);
     }
     public TreeNode findNode(int[] inorder,int inBegin, int inEnd, int[] postorder, int postBegin, int postEnd){
         // 区间是左闭右开的
         if(inBegin >= inEnd || postBegin >= postEnd){
             return null;
         }
         int rootIndex = map.get(postorder[postEnd - 1]);
         TreeNode root = new TreeNode(inorder[rootIndex]);
         int lenOfLeft = rootIndex - inBegin;
         root.left = findNode(inorder, inBegin, rootIndex, postorder, postBegin, postBegin + lenOfLeft);
         root.right = findNode(inorder, rootIndex + 1, inEnd, postorder, postBegin + lenOfLeft, postEnd - 1);
         return root;
     }
 }

105.从前序和中序遍历序列构造二叉树

题目链接:105. 从前序与中序遍历序列构造二叉树 - 力扣(LeetCode)

 class Solution {
 ​
     Map<Integer,Integer> map;
 ​
     public TreeNode buildTree(int[] preorder, int[] inorder) {
         map = new HashMap<>();
         for(int i = 0; i < inorder.length; i++){
             map.put(inorder[i], i);
         }
         return findNode(inorder, 0, inorder.length, preorder, 0, preorder.length);
     }
 ​
     public TreeNode findNode(int[] inorder,int inBegin, int inEnd, int[] preorder, int preBegin, int preEnd){
         // 区间是左闭右开的
         if(inBegin >= inEnd || preBegin >= preEnd){
             return null;
         }
         int rootIndex = map.get(preorder[preBegin]);
         TreeNode root = new TreeNode(inorder[rootIndex]);
         int lenOfLeft = rootIndex - inBegin;
         root.left = findNode(inorder, inBegin, rootIndex, preorder, preBegin + 1, preBegin + lenOfLeft + 1);
         root.right = findNode(inorder, rootIndex + 1, inEnd, preorder, preBegin + lenOfLeft + 1, preEnd);
         return root;
     }
 }