(JAVA)Leetcode 二叉搜索树中的众数 二叉树的最近公共祖先 二叉搜索树的最近公共祖先 二叉搜索树的插入操作

二叉搜索树中的众数

既然是搜索树,中序遍历就是有序的

思路:从头遍历有序数组元素出现的频率,相邻两个元素作比较,把出现频率最高的元素输出。

技巧:1.使用两个指针 pre指针和cur指针 初始时pre=null,所以pre=null时便是比较的第一个元素。

          2.众数很有可能不止一个,所以需要一个数组来存放众数

          3.只需遍历一遍。若count==maxcount,则把这个元素加入到结果集中。

                                      若 count>maxcount,清空结果集,元素加入结果集,maxcount=count

需要全局定义

1.结果集  2.数组集 3.count 4.maxcount

完整代码如下:

递归法

class Solution {
    ArrayList<Integer> reslist;
    int maxcount;
    int count;
    TreeNode pre;
    public int[] findMode(TreeNode root) {
        reslist =new ArrayList<>();
        maxcount=0;
        count=0;
        pre=null;
        findMode1(root);
        int[] list=new int[reslist.size()];
        for(int i=0;i<reslist.size();i++){
            list[i]=reslist.get(i);
        } 
        return list;
    }
    public void findMode1(TreeNode root){
        if(root==null)return;
        findMode1(root.left);
        if(pre==null||root.val!=pre.val){
            count=1;
        }else{
            count++;
        }
        if(count>maxcount){
            reslist.clear();
            reslist.add(root.val);
            maxcount=count;
        }else if(count==maxcount){
            reslist.add(root.val);
        }
        pre=root;
        findMode1(root.right);
    }
}

二叉树的最近公共祖先

返回节点p和节点q的公共祖先

思路:自底向上查找(回溯) ,后序遍历则是天然的回溯过程。

如何判断一个节点是节点p和节点q的公共祖先呢?

答:如果找到一个节点,发现左(右)子树出现节点p,右(左)子树出现节点q,那么该节点就是最近的公共祖先。

递归法

1.确定递归函数参数以及返回值

      参数:treenode root ,p,q

      返回值:最近的公共祖先

2.确定终止条件

      若找到节点p或者q,或者遇到空节点,就返回

3.确定单层递归逻辑

      本题要遍历树的所有节点

      注意:如果left 和 right都不为空,说明此时root就是最近公共节点。

                 如果left为空,right不为空,就返回right,说明目标节点是通过right返回的,反之依然

不懂的话可见下图:

 完整代码如下:

递归法

class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if(root==null||root==p||root==q){
            return root;
        }
        TreeNode left=lowestCommonAncestor(root.left,p,q);
        TreeNode right=lowestCommonAncestor(root.right,p,q);
        if(left==null&&right==null){
            return null;
        }else if(left!=null&&right==null){
            return left;
        }else if(left==null&&right!=null){
            return right;
        }else{
            return root;
        }
    }
}

二叉搜索树的最近公共祖先

要比普通二叉树的公共祖先问题简单得多。

不需要使用回溯,因为二叉搜索树自带方向性。所以我们可以使用前序遍历。(其实遍历顺序无所谓,因为没有中节点的处理逻辑)

而且不需要遍历整棵树,找到结果则直接返回

完整代码如下:

递归法

class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if(root.val>p.val&&root.val>q.val)return lowestCommonAncestor(root.left,p,q);
        if(root.val<p.val&&root.val<q.val)return lowestCommonAncestor(root.right,p,q);
        return root;
    }
}

迭代法

class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        while(true){
            if(root.val>p.val&&root.val>q.val){
                root=root.left;
            }else if(root.val<p.val&&root.val<q.val){
                root=root.right;
            }else{
                break;
            }
        }
        return root;
    }
}

二叉搜索树中的插入操作

思路:本体其实并不复杂,不需要考虑改变树的结构的插入方式。

           只需要遍历二叉树,找到空节点插入元素即可。

递归法

1.确定递归函数参数及返回值

      参数:根节点指针 要插入的元素 

      返回值可有可无

2.确定终止条件

      遍历节点为null时,即是要插入节点的位置,并把插入的节点返回

3.确定单层递归的逻辑

      因为是搜索树,所以不需要完整的遍历整棵树

      因为是有方向的,则可以根据插入元素的数值决定递归的方向

     即if(root.val>val) root.left

        if   (root.val<val)   root.right

完整代码如下:

class Solution {
    public TreeNode insertIntoBST(TreeNode root, int val) {
        if(root==null){
            return new TreeNode(val);
        }
        if(root.val<val){
            root.right=insertIntoBST(root.right,val);
        }else if(root.val>val){
            root.left=insertIntoBST(root.left,val);
        }
        return root;
    }
}

迭代法

需要一个指针pre来记录空节点之前的节点,这样才好判断插入的元素是插入左侧还是右侧

需要一个newroot来返回最后插入新元素的root

完整代码如下:

class Solution {
    public TreeNode insertIntoBST(TreeNode root, int val) {
        if(root==null){
            return new TreeNode(val);
        }
        TreeNode newroot=root;
        TreeNode pre=root;
        while(root!=null){
            pre=root;
            if(root.val>val){
                root=root.left;
            }else if(root.val<val){
                root=root.right;
            }
        }
        if(pre.val>val){
            pre.left=new TreeNode(val);
        }else if(pre.val<val){
            pre.right=new TreeNode(val);
        }
        return newroot;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值