LeetCode喜新厌旧专项-二叉树

二叉树问题一般通过前序遍历、中序遍历、后序遍历以及层序遍历就可以解决,涉及的算法主要为BFS(层次遍历)、DFS(回溯,递归)。

二叉树的最大深度

    int ans=0;
    int depth=0;
    public int maxDepth(TreeNode root) {
        //递归做法
//        if(root==null) return 0;
//        return Math.max(maxDepth(root.left),maxDepth(root.right))+1;
        //遍历,前序就是进入节点的时候,后序就是退出节点的时候
        dfs(root);
        return ans;
    }
    void dfs(TreeNode root){
        if(root==null){
            return;
        }
        depth++;
        dfs(root.left);
        dfs(root.right);
        ans=Math.max(ans,depth);  //labuladong的做法是前序判断叶节点更新ans
        depth--;
    }

124 二叉树的最大路径和

    int ans=Integer.MIN_VALUE;
    public int maxPathSum(TreeNode root) {
        dfs(root);
        return ans;
    }
    int dfs(TreeNode root){
        if(root==null) return 0;
        int left=dfs(root.left);
        int right=dfs(root.right);
        int tmp= root.val;
        if(left>=0){
            tmp+=left;
        }
        if(right>=0){
            tmp+=right;
        }
        ans=Math.max(ans,tmp);
        //要不要左右子树取决于加入子树后该节点的值是不是比当前节点大
        return Math.max(root.val,Math.max(left,right)+root.val);
    }

102 二叉树的层序遍历

 public List<List<Integer>> levelOrder(TreeNode root) {
        if(root==null) return new ArrayList<>();
        List<List<Integer>> ans=new ArrayList<>();
        Queue<TreeNode> q=new LinkedList<>();
        q.offer(root);
        while(q.size()!=0){
            List<Integer> tmp=new ArrayList<>();
            int curSize=q.size();
            for(int i=0;i<curSize;i++){
                TreeNode node=q.poll();
                tmp.add(node.val);
                if(node.left!=null) q.offer(node.left);
                if(node.right!=null) q.offer(node.right);
            }
            ans.add(tmp);
        }
        return ans;
    }

617 合并二叉树

    public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
        if(root1==null) return root2;
        if(root2==null) return root1;
        TreeNode merge= new TreeNode(root1.val+root2.val);
        merge.left=mergeTrees(root1.left,root2.left);
        merge.right=mergeTrees(root1.right,root2.right);
        return merge;
    }

230 二叉搜索树中第K小的数

    int ans;
    int k;
    public int kthSmallest(TreeNode root, int k) {
        this.k=k;
        dfs(root);
        return ans;
    }
    void dfs(TreeNode root){
        if(root==null) return;
        dfs(root.left);
        k--;
        if(k==0)  ans=root.val;
        dfs(root.right);
    }

226 翻转二叉树

    public TreeNode invertTree(TreeNode root) {
        if (root==null) return null;
        // 需要暂存root.left,避免覆盖
        TreeNode node=root.left;
        root.left=invertTree(root.right);
        root.right=invertTree(node);
        return root;
    }

101 对称二叉树

    public boolean isSymmetric(TreeNode root) {
        if(root==null) return true;
        return dfs(root.left,root.right);
    }
    boolean dfs(TreeNode left,TreeNode right){
        if(left==null && right==null) return true;
        if(left==null || right==null) return false;
        return (left.val==right.val) && dfs(left.left,right.right)
                && dfs(left.right,right.left);
    }

543 二叉树的直径

    int ans;
    public int diameterOfBinaryTree(TreeNode root) {
        ans=1;
        depth(root);
        return ans-1;
    }
    //返回当前节点的深度
    int depth(TreeNode root){
        if (root==null) return 0;
        int l=depth(root.left);
        int r=depth(root.right);
        ans=Math.max(ans,l+r+1);
        return Math.max(l,r)+1;
    }

222 完全二叉树的节点个数

    int ans=0;
    public int countNodes(TreeNode root) {
        dfs(root);
        return ans;
    }
    void dfs(TreeNode root){
        if(root==null) return ;
        ans++;
        dfs(root.left);
        dfs(root.right);
    }

257 二叉树的所有路径

    List<String> ans=new ArrayList<>();
    StringBuilder sb=new StringBuilder();
    public List<String> binaryTreePaths(TreeNode root) {
        dfs(root);
        return ans;
    }
    void dfs(TreeNode root){
        if(root==null) return;
        int t=sb.length();
        sb.append(root.val);
        if(root.left==null && root.right==null){
            ans.add(sb.toString());
        }else{
            sb.append("->");
        }
        dfs(root.left);
        dfs(root.right);
        //离开叶节点时一步一步删除
        sb.delete(t,sb.length());
    }

404 左叶子之和

    int ans;
    public int sumOfLeftLeaves(TreeNode root) {
        dfs(root);
        return ans;
    }
    void dfs(TreeNode root){
        if(root==null) return ;
        if(root.left!=null && root.left.left==null && root.left.right==null)
            ans+=root.left.val;
        dfs(root.left);
        dfs(root.right);
    }

501 二叉搜索树中的众数

    HashMap<Integer,Integer> map=new HashMap<>();
    public int[] findMode(TreeNode root) {
        dfs(root);
        List<Integer> ans=new ArrayList<>();
        //得到最大次数
        int maxTime=0;
        for(Integer k: map.keySet()){
            int temp=map.get(k);
            maxTime=temp>=maxTime? temp:maxTime;
        }
        //得到ans
        for(Integer v: map.keySet()){
            if(map.get(v)==maxTime){
                ans.add(v);
            }
        }
        return ans.stream().mapToInt(Integer::valueOf).toArray();
    }
    void dfs(TreeNode root){
        if (root==null) return;
        dfs(root.left);
        int key=root.val;
        map.put(key,map.getOrDefault(key,0)+1);
        dfs(root.right);
    }

530 二叉树的最小绝对差

    List<Integer> list=new ArrayList<>();
    public int getMinimumDifference(TreeNode root) {
        dfs(root);
        int ans=Integer.MAX_VALUE;
        for(int i=0;i< list.size()-1;i++){
            if(ans>(list.get(i+1)-list.get(i))){
                ans=list.get(i+1)-list.get(i);
            }
        }
        return ans;
    }
    void dfs(TreeNode root){
        if (root==null) return ;
        dfs(root.left);
        list.add(root.val);
        dfs(root.right);
    }

563 二叉树的坡度

    public int findTilt(TreeNode root) {
        if (root==null) return 0;
        return findTilt(root.left)+findTilt(root.right)+sum(root);
    }
    int sum(TreeNode root){
        return Math.abs(recur(root.left)-recur(root.right));
    }
    int recur(TreeNode root){
        if (root==null) return 0;
        int l=recur(root.left);
        int r=recur(root.right);
        return l+r+root.val;
    }

572 另一棵树的子树

    public boolean isSubtree(TreeNode root, TreeNode subRoot) {
        return dfs(root,subRoot);
    }
    boolean dfs(TreeNode root, TreeNode subRoot){
        if (root==null) return false;
        return check(root,subRoot)
                || isSubtree(root.left,subRoot) || isSubtree(root.right,subRoot);
    }
    boolean check(TreeNode root, TreeNode subRoot){
        if(root==null && subRoot==null)
            return true;
        if(root==null || subRoot==null || root.val!=subRoot.val)
            return false;
        return check(root.left,subRoot.left)
                && check(root.right,subRoot.right);
    }
    //提交2
    public boolean isSubtree(TreeNode root, TreeNode subRoot) {
        if(root==null || subRoot==null)
            return false;
        return dfs(root,subRoot) || isSubtree(root.left,subRoot)
                || isSubtree(root.right,subRoot);
    }
    boolean dfs(TreeNode root, TreeNode subRoot){
        if(root==null && subRoot==null)
            return true;
        if(root==null || subRoot==null || root.val!=subRoot.val)
            return false;
        return dfs(root.left,subRoot.left)
                && dfs(root.right,subRoot.right);
    }

637 二叉树的层平均值

    public List<Double> averageOfLevels(TreeNode root) {
        List<Double> ans=new ArrayList<>();
        if (root==null) return ans;
        Queue<TreeNode> pq=new LinkedList<>();
        pq.add(root);
        while (!pq.isEmpty()){
            int curSize=pq.size();
            double level=0;
            int count=0;
            for(int i=0;i<curSize;i++){
                TreeNode node=pq.poll();
                level+=node.val;
                count++;
                if(node.left!=null) pq.add(node.left);
                if(node.right!=null) pq.add(node.right);
            }
            ans.add(level/count);
        }
        return ans;
    }

653 两数之和-二叉搜索树

    HashSet<Integer> set=new HashSet<>();
    public boolean findTarget(TreeNode root, int k) {
        return dfs(root,k);
    }
    //返回当前k-当前节点值的值是否在set中
    boolean dfs(TreeNode root,int k){
        if(root==null) return false;
        if (set.contains(k-root.val)){
            return true;
        }
        set.add(root.val);
        return dfs(root.left,k) || dfs(root.right,k);
    }

671 二叉树中第二小的节点

    Set<Integer> set=new HashSet<>();
    public int findSecondMinimumValue(TreeNode root) {
        dfs(root);
        //记住set,list转数组的做法-stream流的方式
        int[] arr=set.stream().mapToInt(Integer::intValue).toArray();
        Arrays.sort(arr);
        return arr.length<=1? -1:arr[1];
    }
    void dfs(TreeNode root){
        if(root==null) return;
        set.add(root.val);
        dfs(root.left);
        dfs(root.right);
    }

700 二叉搜索树中的搜索

    TreeNode ans;
    public TreeNode searchBST(TreeNode root, int val) {
        dfs(root,val);
        return ans;
    }
    void dfs(TreeNode root,int val){
        if (root==null) return;
        if(root.val==val)  ans=root;
        dfs(root.left,val);
        dfs(root.right,val);
    }

872 叶子相似的树

    public boolean leafSimilar(TreeNode root1, TreeNode root2) {
        List<Integer> set1=new ArrayList<>();
        dfs(root1,set1);
        List<Integer> set2=new ArrayList<>();
        dfs(root2,set2);
        if (set1.size()==set2.size()){
            for(int i=0;i<set1.size();i++){
                if(!set1.get(i).equals(set2.get(i))) return false;
            }
            return true;
        }
        return false;
    }
    void dfs(TreeNode root,List<Integer> s){
        if(root==null) return ;
        if(root.left==null && root.right==null){
            s.add(root.val);
        }
        dfs(root.left,s);
        dfs(root.right,s);
    }

897 递增顺序搜索树

    List<Integer> ans=new ArrayList<>();
    public TreeNode increasingBST(TreeNode root) {
        TreeNode dumy=new TreeNode() ;
        TreeNode temp=dumy;
        dfs(root);
        for(int i=0;i< ans.size();i++){
            temp.right=new TreeNode(ans.get(i));
            temp=temp.right;
        }
        return dumy.right;
    }
    void dfs(TreeNode root){
        if(root==null) return;
        dfs(root.left);
        ans.add(root.val);
        dfs(root.right);
    }

938 二叉搜索树的范围和

    int ans;
    public int rangeSumBST(TreeNode root, int low, int high) {
        dfs(root,low,high);
        return ans;
    }
    void dfs(TreeNode root,int low,int high){
      if (root==null) return;
      if(root.val>=low && root.val<=high) ans+=root.val;
      dfs(root.left,low,high);
      dfs(root.right,low,high);
    }

965 单值二叉树

    List<Integer> list=new ArrayList<>();
    public boolean isUnivalTree(TreeNode root) {
        int n;
        if(root==null) return false;
        else n=root.val;
        boolean flag;
        dfs(root);
        for(int i=1;i<list.size();i++){
            if(list.get(i)!=n){
                return false;
            }
        }
        return true;
    }
    void dfs(TreeNode root){
        if(root==null) return;
        list.add(root.val);
        dfs(root.left);
        dfs(root.right);
    }

993 二叉树的堂兄弟节点

    public boolean isCousins(TreeNode root, int x, int y) {
        Queue<TreeNode> pq=new LinkedList<>();
        pq.add(root);
        while(!pq.isEmpty()){
            int sz=pq.size();
            int countX=0,countY=0;
            for(int i=0;i<sz;i++){
                TreeNode node=pq.poll();
                if(node.val==x) countX=1;
                if(node.val==y) countY=1;
                if(node.left!=null && node.right!=null){
                    int left=node.left.val,right=node.right.val;
                    if((left==x && right==y) || (right==x&&left==y))
                        return false;
                }
                if (node.left!=null) pq.add(node.left);
                if(node.right!=null) pq.add(node.right);
            }
            if(countX==1&&countY==1) return true;
        }
        return false;
    }

1379 找出克隆二叉树中的相同节点

    TreeNode ans;
    public final TreeNode getTargetCopy(final TreeNode original, final TreeNode cloned, final TreeNode target) {
        dfs(cloned,target);
        return ans;
    }
    void dfs(TreeNode cloned,TreeNode target){
        if (cloned==null) return ;
        if(cloned.val==target.val) ans=cloned;
        dfs(cloned.left,target);
        dfs(cloned.right,target);
    }

2236 判断根节点是否等于子结点之和

    public boolean checkTree(TreeNode root) {
        int tar;
        if (root==null) return false;
        else tar= root.val;
        return (dfs(root.left)+dfs(root.right))==tar;
    }
    int dfs(TreeNode root){
        if (root==null) return 0;
        return root.val+dfs(root.left)+dfs(root.right);
    }

2331 计算布尔二叉树的值

    public boolean evaluateTree(TreeNode root) {
        if (root.left==null) return root.val==1;
        if(root.val==2){
            return evaluateTree(root.left) || evaluateTree(root.right);
        }else{
            return evaluateTree(root.left) && evaluateTree(root.right);
        }
    }

LCP44 开幕式焰火

    Set<Integer> set=new HashSet<>();
    public int numColor(TreeNode root) {
        dfs(root);
        return set.size();
    }
    void dfs(TreeNode root){
        if (root==null) return;
        set.add(root.val);
        dfs(root.left);
        dfs(root.right);
    }

面试04.02 最小高度树

    //将中间的树当根节点,左边当左子树,右边右子树
    public TreeNode sortedArrayToBST(int[] nums) {
       return dfs(nums,0,nums.length-1);
    }
    TreeNode dfs(int[] nums,int i,int j){
        if(i>j) return null;
        int mid=(int)Math.ceil((i+j)/2.0);
        TreeNode node=new TreeNode(nums[mid]) ;
        node.left=dfs(nums,i,mid-1);
        node.right=dfs(nums,mid+1,j);
        return node;
    }

04.04 检查平衡性

    public boolean isBalanced(TreeNode root) {
        if (root==null) return true;
        return Math.abs(height(root.left)-height(root.right))<=1
                && isBalanced(root.left)
                && isBalanced(root.right);
    }
    int height(TreeNode root){
        if (root==null) return 0;
        return Math.max(height(root.left),height(root.right))+1;
    }

LCR144 翻转二叉树

    public TreeNode mirrorTree(TreeNode root) {
        return dfs(root);
    }
    TreeNode dfs(TreeNode root){
        if(root==null) return null;
        //思考为什么不能TreeNode ans=root;不知道是不是内存引用的问题,new创建新的引用,=去堆中找
        TreeNode ans=new TreeNode(root.val); 
        ans.left=dfs(root.right);
        ans.right=dfs(root.left);
        return ans;
    }

LCR 144 推理(重建)二叉树

    //借助辅助结构,全局preorder,以及map
    int[] preorder;
    Map<Integer,Integer> map=new HashMap<>();
    public TreeNode deduceTree(int[] preorder, int[] inorder) {
        this.preorder=preorder;
        for (int i=0;i<inorder.length;i++){
            map.put(inorder[i],i);
        }
        return recur(0,0,inorder.length-1);
    }
    TreeNode recur(int root, int left, int right){ //根节点位置,子树的左端-右端
        if(left>right) return null;
        TreeNode node=new TreeNode(preorder[root]);
        //map记录了前序的节点在中序的索引,方便分割
        int i=map.get(preorder[root]);
        node.left=recur(root+1,left,i-1); //递归分段-左子树
        //右子树,右子树的根索引计算方式为:根节点索引+左子树长度+1
        node.right=recur(root+i-left+1,i+1,right);
        return node;
    }
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值