代码随想录刷题——二叉树 day19-20

58 阅读6分钟

第六章 二叉树 part06

今日内容 

●  654.最大二叉树 

●  617.合并二叉树 

●  700.二叉搜索树中的搜索 

●  98.验证二叉搜索树  详细布置


654.最大二叉树

/**
     * Definition for a binary tree node.
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode() {}
     *     TreeNode(int val) { this.val = val; }
     *     TreeNode(int val, TreeNode left, TreeNode right) {
     *         this.val = val;
     *         this.left = left;
     *         this.right = right;
     *     }
     * }
     */
    class Solution {
        public TreeNode constructMaximumBinaryTree(int[] nums) {
            if(nums.length==0)
                return null;
            return traversal(nums,0,nums.length);
        }
        //涉及到二分的话  这里还是沿用左开右闭  统一左闭右开
        public TreeNode traversal(int[] nums,int begin,int end){
            //因为是左闭右开 所以end-begin<1的时候 就是没有元素
            if(end-begin<1){
                return null;
            }
            //只有一个元素
            if(end-begin==1){
                //因为是左闭右开 所以是nums[begin]  右开 最右边的一直都是无用的
                return new TreeNode(nums[begin]);
            }
            //寻找切割点————即是从[begin,end)这个区间段最大的那个元素
            int maxValue=Integer.MIN_VALUE;
            int delimiter=0;
            for(int i=begin;i<end;i++){
                if(nums[i]>maxValue){
                    maxValue=nums[i];
                    delimiter=i;
                }
            }
            TreeNode root=new TreeNode(nums[delimiter]);
            //然后依次向左切 以及 向右切
            root.left=traversal(nums,begin,delimiter);
            root.right=traversal(nums,delimiter+1,end);
            return root;
        }
    }

617.合并二叉树

这次是一起操作两个二叉树了

通过递归,二叉树的前序遍历—— 中左右

将树2 合并到 树1中。


    /**
     * Definition for a binary tree node.
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode() {}
     *     TreeNode(int val) { this.val = val; }
     *     TreeNode(int val, TreeNode left, TreeNode right) {
     *         this.val = val;
     *         this.left = left;
     *         this.right = right;
     *     }
     * }
     */
    class Solution {
        public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
            if(root1==null)
                return root2;
            if(root2==null)
                return root1;
            root1.val+=root2.val;
            root1.left=mergeTrees(root1.left,root2.left);
            root1.right=mergeTrees(root1.right,root2.right);
            return root1;
        }
    }

700.二叉搜索树中的搜索

二叉搜索树的特性 递归方法


    /**
     * Definition for a binary tree node.
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode() {}
     *     TreeNode(int val) { this.val = val; }
     *     TreeNode(int val, TreeNode left, TreeNode right) {
     *         this.val = val;
     *         this.left = left;
     *         this.right = right;
     *     }
     * }
     */
    class Solution {
        //考虑使用递归的方法 结合二叉树的前序遍历
        public TreeNode searchBST(TreeNode root, int val) {
            if(root==null)
                return null;
            if(root.val==val)
                return root;
            //前序遍历————中左右
            //递归左子树  如果找到  就return  
            TreeNode leftRes=searchBST(root.left,val);
            if(leftRes!=null){
                return leftRes;
            }
            //否则递归右子树
            return searchBST(root.right,val);
        }
    }

迭代方法

  /**
     * Definition for a binary tree node.
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode() {}
     *     TreeNode(int val) { this.val = val; }
     *     TreeNode(int val, TreeNode left, TreeNode right) {
     *         this.val = val;
     *         this.left = left;
     *         this.right = right;
     *     }
     * }
     */
    class Solution {
        //使用迭代法  结合二叉搜索树的特性
        public TreeNode searchBST(TreeNode root, int val) {
            if(root==null){
                return null;
            }
            TreeNode curNode=root;
            while(curNode!=null){
                if(curNode.val==val)
                    return curNode;
                if(val<curNode.val){
                    curNode=curNode.left;
                }
                else
                    curNode=curNode.right;
            }
            return curNode;
        }
    }

98.验证二叉搜索树

这道题主要是利用二叉搜索树的特性——二叉搜索树它的中序遍历结果是升序的。

所以可以推断:只要我们将这棵树进行中序遍历,将其结果存储到数组中,只要其是升序的,那么我们就可以说他是二叉搜索树。

注意: 这里有一个我个人碰到的点:

在for循环中进行判断时,不能写成如下形式:(数值会溢出!!) 因为它极有可能是一个很大的正数减去一个负数。

 for(int i=list.size()-1;i>0;i--){
                if(list.get(i)-list.get(i-1)<=0)
                    return false;
            }


/**
     * Definition for a binary tree node.
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode() {}
     *     TreeNode(int val) { this.val = val; }
     *     TreeNode(int val, TreeNode left, TreeNode right) {
     *         this.val = val;
     *         this.left = left;
     *         this.right = right;
     *     }
     * }
     */
     //考虑利用二叉搜索树的特性  二叉搜索树-中序遍历左中右 遍历出来它是升序的
    class Solution {
        public boolean isValidBST(TreeNode root) {
            if(root.left==null && root.right==null)
                return true;
            List<Integer> list=new ArrayList<>();
            traversal(root,list);
            //因为上面的if语句已经判断了仅有一个根节点的情况 所以接下来树至少有两个节点
            for(int i=list.size()-1;i>0;i--){
                if(list.get(i)<=list.get(i-1))
                    return false;
            }
            return true;
    
        }
        public void traversal(TreeNode node,List<Integer> list){
            if(node==null){
                return;
            }
            traversal(node.left,list);
            list.add(node.val);
            traversal(node.right,list);
        }
    }

第六章 二叉树part07

今日内容 

●  530.二叉搜索树的最小绝对差 

●  501.二叉搜索树中的众数 

●  236. 二叉树的最近公共祖先   详细布置


530.二叉搜索树的最小绝对差

个人错误思想(自查):

看到这道题并且结合力扣上面给的两个示例,想当然认为最小绝对差一定是在当前节点与其左右子节点之间产生。 然而这是错误的。

比如一棵树如下图所示,其最少绝对差是236-227 这两者并不是在相邻的层之间。

Snipaste_2024-03-13_21-46-47.png

错误的代码

/**
     * Definition for a binary tree node.
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode() {}
     *     TreeNode(int val) { this.val = val; }
     *     TreeNode(int val, TreeNode left, TreeNode right) {
     *         this.val = val;
     *         this.left = left;
     *         this.right = right;
     *     }
     * }
     */
    class Solution {
        //尝试迭代层序遍历  暴力搜索
        //猜测两值之差的最小值 一定在 某个节点及其子节点之间产生
        public int getMinimumDifference(TreeNode root) {
            int minVal=Integer.MAX_VALUE;
            Queue<TreeNode> queue=new LinkedList<>();
            //层序遍历要使用队列
            queue.offer(root);
            while(!queue.isEmpty()){
                //len 是queue的长度 另一方面指代的也是当前遍历的层数的所有节点数量
                int len=queue.size();
                while(len>0){
                    //获取当前层的节点
                    TreeNode curNode=queue.poll();
                    len--;
                    //如果有左子节点的话  入队
                    if(curNode.left!=null){
                        queue.offer(curNode.left);
                        //计算当前节点与其左子节点的差值  更新minVal的值
                        if(curNode.val-curNode.left.val<minVal){
                            minVal=curNode.val-curNode.left.val;
                        }
                    }
                    //右子节点操作同上
                    if(curNode.right!=null){
                        queue.offer(curNode.right);
                        //根据二叉搜索树的概念,右子节点的数值是要大于当前节点的值
                        if(curNode.right.val-curNode.val < minVal){
                            minVal=curNode.right.val-curNode.val;
                        }
                    }
                }
            }
            return minVal;
        }
    }

其实正确的方法也很简单,就是直接将题中所给的二叉搜索树进行中序遍历,然后将其存入到数组中,依次再两两比较即可。

这里学习&实现直接在二叉搜索树中实现双指针。

具体思想看代码注释

/**
     * Definition for a binary tree node.
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode() {}
     *     TreeNode(int val) { this.val = val; }
     *     TreeNode(int val, TreeNode left, TreeNode right) {
     *         this.val = val;
     *         this.left = left;
     *         this.right = right;
     *     }
     * }
     */
    class Solution {
        TreeNode pre;
        int minVal=Integer.MAX_VALUE;
        public int getMinimumDifference(TreeNode root) {
           traversal(root);
           return minVal;
        }
        //直接在二叉搜索树中使用双指针。即一个指针指向当前节点,另一个指针指向当前节点的中序遍历的上一个结点
        //因为只有在二叉搜索树中 使用双指针才能达到 将所有数值存入到数组中再两两比对的效果
        public void traversal(TreeNode node){
            if(node==null){
                return;
            }
            //中序遍历 左中右
            //左
            traversal(node.left);
            //中
            if(pre!=null){
                minVal=node.val-pre.val<minVal? (node.val-pre.val):minVal;
            }
            pre=node;
            //右
            traversal(node.right);


        }

    }

501.二叉搜索树中的众数

 /**
     * Definition for a binary tree node.
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode() {}
     *     TreeNode(int val) { this.val = val; }
     *     TreeNode(int val, TreeNode left, TreeNode right) {
     *         this.val = val;
     *         this.left = left;
     *         this.right = right;
     *     }
     * }
     */
    class Solution {
        int MaxCount=0;
        int count=0;
        TreeNode pre=new TreeNode();
        public int[] findMode(TreeNode root) {
            List<Integer> resList=new ArrayList<>();
            traversal(root,resList);
            int[] result=new int[resList.size()];
            for(int i=0;i<resList.size();i++){
                result[i]=resList.get(i);
            }
            return result;

        }
        //考虑使用中序遍历  将二叉搜索树中的所有节点存入到list之中  
        public void traversal(TreeNode node,List<Integer> resList){
            //中序遍历 左中右
            //如果当前节点为空
            if(node==null){
                return;
            }
            //左
            traversal(node.left,resList);
            //中
            //获取当前节点的数值
            int curNodeVal=node.val;
            //如果当前节点是第一个节点(pre==null) 或者节点的值发生了跳转
            if(pre==null || curNodeVal!=pre.val){
                count=1;
            }
            else{
                count++;
            }
            //更新结果
            if(count>MaxCount){
               resList.clear();
                MaxCount=count;

                resList.add(node.val);
            }
            else if(count==MaxCount){
                resList.add(node.val);
            }
            pre=node;
            //右
            traversal(node.right,resList);

        }
    }

236. 二叉树的最近公共祖先

难以理解