代码随想录算法训练营第十八天| 513.找树左下角的值,112. 路径总和,106.从中序与后序遍历序列构造二叉树

513. Find Bottom Left Tree Value

  • 思路
    • 递归
    • java
      
      
      class Solution {
          int maxDep = Integer.MIN_VALUE;
          int res = 0;
          public int findBottomLeftValue(TreeNode root) {
              res = root.val;
              helper(root, 0);
              return res;
          }
          private void helper(TreeNode root, int depth){
              if( root == null){
                  return;
              }
              if( root.left == null && root.right == null){
                  if(depth > maxDep){
                      res = root.val;
                      maxDep = depth;
                  }
              }
              
              if (root.left != null){
                  depth++;
                  helper(root.left, depth);
                  depth--; //backtrack
              }
              if (root.right != null){
                  depth++;
                  helper(root.right, depth);
                  depth--;
              }
              
          }
      }
    • 迭代
      • BFS不断更新res直到最后一层的第一个数
      • java
        class Solution {
            public int findBottomLeftValue(TreeNode root) {
               int res = 0;
               Queue queue = new LinkedList<>();
               queue.add(root);
               while(!queue.isEmpty()){
                   int size = queue.size();
                   int first = size;
                   while (size > 0){
                       TreeNode temp = queue.poll();
                       if(size == first){
                           res = temp.val;
                       }
                       if(temp.left != null){
                           queue.add(temp.left);
                       }
                       if(temp.right != null){
                           queue.add(temp.right);
                       }
                       size--;
                   }
               }
               return res;
            }
        }

112. Path Sum

  • 思路:
  • DFS 带回溯/不带回溯都可以
  • java
    //这个是卡哥的写法,带回溯
    class Solution {
        public boolean hasPathSum(TreeNode root, int targetSum) {
            if (root == null) {
                return false;
            }
            return helper(root, targetSum - root.val);
        }
        
        private boolean helper(TreeNode root, int count){
            if (root.left == null && root.right == null){
            return count == 0;
            }
            
            if (root.left != null){
                count -= root.left.val;
                if(helper (root.left, count)){
                    return true;
            }
                count += root.left.val;
                
            }
            if (root.right != null){
                count -= root.right.val;
                if(helper (root.right, count)){
                    return true;
                }
                count += root.right.val;
            }
        return false;
        }
    }
    
    //这个写法相当于前序遍历,这里还涉及到一个基本数据类型值拷贝,不会应为function内部的变换导致参数的变化,所以不用回溯。如果是list之类的话就不行了
    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){ //左
               // targetSum -= root.left.val;
                if( hasPathSum(root.left, targetSum)){
                    return true;
                }
                //targetSum += root.left.val;
                
            }
            if(root.right != null){  //右
                //targetSum -= root.right.val;
                if(hasPathSum(root.right, targetSum)){
                    return true;
                }
                //targetSum += root.right.val;
            }
            return false;
        }
    }
  • BFS迭代
    • 用一个queue同步存sum的值,到叶子节点比较下如果sum == targetSum就返回true
    • 这个因为除了最后一层其他节点都会遍历,所以会比DFS慢一点,TC反正都是N
    • java
      class Solution {
          public boolean hasPathSum(TreeNode root, int targetSum) {
              if (root == null) return false;
              Queue queue1 = new LinkedList<>();
              Queue queue2 = new LinkedList<>();
              queue1.add(root);
              queue2.add(root.val);
              while(!queue1.isEmpty()){
                  int size = queue1.size();
                  for(int i = 0; i< size; i++){
                      TreeNode temp = queue1.poll();
                      int tempNum = queue2.poll();
                      if(temp.left == null && temp.right == null && tempNum == targetSum){
                          return true;
                      }
                      if(temp.left != null){
                          queue1.add(temp.left);
                          queue2.add(tempNum + temp.left.val);
                      }
                      if(temp.right != null){
                          queue1.add(temp.right);
                          queue2.add(tempNum + temp.right.val);
                      }
                  }
              }
              return false;
          }
      }

 113. Path Sum II

  • 思路
    • 跟[[112. Path Sum]]一样DFS,这里要求返回具体List所以必须带回溯
    • 
      
      class Solution {
          public List> pathSum(TreeNode root, int targetSum) {
              List> res = new ArrayList<>();
              if (root == null) {
                  return res;
              }
              List path = new LinkedList<>();
              helper(root, targetSum, path, res);
              return res;
          }
          
          private void helper(TreeNode root, int targetSum, List path, List> res){
              path.add(root.val);
              if( root.left == null && root.right == null){
                  if(targetSum - root.val == 0){
                      res.add(new ArrayList<>(path));
                  }
                  return;
              }
              if(root.left != null){
                  helper(root.left, targetSum - root.val, path, res);
                  path.remove(path.size()-1);
              }
              if(root.right != null){
                  helper(root.right, targetSum -root.val, path, res);
                  path.remove(path.size()-1);
              }
          }
      }

106. Construct Binary Tree from Inorder and Postorder Traversal

  • 思路
    • 从postorder确定中节点
    • 在inoreder里找到这个中节点,从而分割左右子树
      • 中节点左边的就是左子树,可以求出左子树的长度
      • 已知中结点,左子树长度,可求出右子树长度
      • 然后根据左右子树长度以及inorder posterorder的特性,DFS递归
      • java
        class Solution {
            Map 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 helper(inorder, 0, inorder.length, postorder, 0, postorder.length);
            }
            private TreeNode helper(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 = helper(inorder, inBegin, rootIndex, postorder, postBegin, postBegin+ lenOfLeft);
                root.right = helper(inorder, rootIndex+1, inEnd, postorder, postBegin+ lenOfLeft, postEnd -1);
                
                return root;
            }
        }

 105. Construct Binary Tree from Preorder and Inorder Traversal

 

  • 思路
    • 与[[106. Construct Binary Tree from Inorder and Postorder Traversal]]相同
    • java
      class Solution {
          Map 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 helper(preorder, 0, preorder.length, inorder, 0, inorder.length);
          }
          private TreeNode helper(int[] preorder, int preBegin, int preEnd, int[] inorder, int inBegin, int inEnd){
              if(preBegin >= preEnd || inBegin >=inEnd){
                  return null;
              }
              int rootIndex = map.get(preorder[preBegin]);
              TreeNode root = new TreeNode (inorder[rootIndex]);
              int lenOfLeft = rootIndex - inBegin;
              root.left = helper(preorder, preBegin + 1, preBegin + 1 + lenOfLeft, inorder, inBegin, rootIndex );
              root.right = helper(preorder, preBegin + 1+ lenOfLeft, preEnd, inorder,  rootIndex+1, inEnd);
              return root;
          }
      }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值