二叉查找树(重复元素情况)

二叉树查找元素的位置(含有重复元素,且元素个数是不确定的)
题目

代码解析

package 在排序数组中查找第一个元素与最后一个元素;

public class Solution {
    public int[] searchRange(int[] nums, int target) {
        int[] result =new int[2];
        result[0] = findFirstLeft2(nums,target);
        result[1] = findFirstRight2(nums,target);
        return result;
    }
    /*
    * 查找第一个与最后一个元素,说明排序数组是含有重复元素的(原来的二叉树是不含相同元素的)
    * 所以这里要做一些小的调整
    * */
//正常不包含重复元素时利用二分查找法查找元素
    public static int findFirstLeft(int[] nums, int target){
        int left = 0;
        int right = nums.length-1;
        while (left <= right){
            int mid = left+(right-left+1)/2;
            //比较目标值和中间值的大小;
            if(nums[mid] > target){
                //说明目标值在mid的左边,缩小范围
                right = mid-1;
            }else if(nums[mid] < target){
                left = mid+1;
            }else {
                return mid;
            }
        }
        return -1;
    }
//包含相同元素,则要判断该元素是首元素还是末元素。
    public static int findFirstLeft2(int[] nums , int target){
        int left = 0;
        int right = nums.length-1;
        while (left <= right){
            int mid = left+(right-left+1)/2;
            //比较目标值和中间值的大小;
            if(nums[mid] > target){
                //说明目标值在mid的左边,缩小范围
                right = mid-1;
            }else if(nums[mid] < target){
                left = mid+1;
            }else {
                //因为该数组是按照升序排序的,所以只要判断该元素
                //前一个元素是否相同,就知道该元素是第一个还是第二个
                if(mid == 0 || nums[mid] != nums[mid-1]){//mid == 0是防止mid-1超出数组范围。
                    //说明mid就是第一个元素
                    return mid;
                }else {
                    //说明该元素前面还有相同的元素,但是具体有几个,我们不秦楚
                    //所以我们不能直接返回前一个元素的位置,而是缩小范围,继续找第一个元素。
                    right = mid-1;
                }
            }
        }
        return -1;
    }

    //查找最后一个元素的位置
    public static int findFirstRight2(int[] nums , int target){
        int left = 0;
        int right = nums.length-1;
        while (left <= right){
            int mid = left+(right-left+1)/2;
            //比较目标值和中间值的大小;
            if(nums[mid] > target){
                //说明目标值在mid的左边,缩小范围
                right = mid-1;
            }else if(nums[mid] < target){
                left = mid+1;
            }else {
                //因为该数组是按照升序排序的,所以只要判断该元素
                //前一个元素是否相同,就知道该元素是第一个还是第二个
                if(mid == nums.length-1 || nums[mid] != nums[mid+1]){//如果mid为最后一个元素,就不存在下一个元素了
                    //说明mid就是第一个元素
                    return mid;
                }else {
                    //说明该元素前面还有相同的元素,但是具体有几个,我们不秦楚
                    //所以我们不能直接返回前一个元素的位置,而是缩小范围,继续找第一个元素。
                    left = mid+1;
                }
            }
        }
        return -1;
    }


}

代码解读

相比于传统的二叉树查找,多了一步判断元素是第一元素还是最后元素的操作。代码中都有解析。

复杂度分析

时间复杂度:O(logn)
空间复杂度:O(1)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

仰望星空的鑫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值