在排序数组中查找元素的第一个和最后一个位置/二分查找进阶

本文介绍了如何在已排序的数组中,使用二分查找法找到目标值的第一个和最后一个位置。提供了两种解决方案,一种是通过前后搜索,另一种是利用二分查找的优化技巧实现更高效的查找过程。

给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。
如果数组中不存在目标值,返回 [-1, -1]。


方法一:
从前往后找target的值
从后往前找target的值
然后用left和right分别记录下来

class Solution {
   public static int[] searchRange(int[] nums, int target) {
       if(nums.length == 0){
           return new int[]{-1,-1};
       }
        int left = 0;
        int right = nums.length - 1;
        //从前往后找等于target的元素,从后往前找等于target的元素
        while (left < right){
            while (left < right && nums[left] < target){
                left++;
            }
            while (left < right && nums[right] > target){
                right--;
            }
            if (nums[left] == target && nums[right] == target){
                break;
            }
        }
        if (nums[left] == target && nums[right] == target){
            return new int[] {left,right};
        }
        return new int[]{-1,-1};
    }
}

方法二:二分查找(leetcode官方解答)
*
寻找左侧边界的二分查找

	public static int left_bound(int[] nums, int target) {
        if (nums.length == 0) return -1;
        int left = 0;
        int right = nums.length; // 注意

        while (left < right) { // 注意
            int mid = (left + right) / 2;
            if (nums[mid] == target) {
                right = mid;
            } else if (nums[mid] < target) {
                left = mid + 1;
            } else if (nums[mid] > target) {
                right = mid; // 注意
            }
        }
        if (left == nums.length) return -1;
        // 类似之前算法的处理方式
        return nums[left] == target ? left : -1;
    }

寻找右侧边界的二分查找

	public static int rightBinary(int[] nums,int target){
        int left = 0;
        int right = nums.length;
        while (left < right){
            int mid = (left + right) / 2;
            if (nums[mid] == target){
                left = mid + 1;
            }else if (nums[mid] < target){
                left = mid + 1;
            }else if (nums[mid] > target){
                right = mid;
            }
        }
        if (left == 0 ){
            return -1;
        }
        return nums[left - 1] == target ? left -1 : -1;
    }
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值