力扣第34题 【在排序数组中查找元素的第一个和最后一个位置】

本题本质上还是对二分查找的应用,区别在于当判断nums[mid]==target时,普通二分查找直接返回,而本题目却依旧要移动边界。

把问题简化一下,找第一个位置和最后位置分别用一次二分查找,在left=right时跳出循环。

先看寻找左边界,当目标值与mid对应的相同时,让右边界移动到mid,因为此时mid右边的所有值都是大于等于目标值,寻找的是最左值所以将左边部分舍去。

var searchLeft= function(nums,target){
    //[]区间
    let left=0,right=nums.length-1;
    while(left<right){
        let mid=Math.floor((left+right)/2);
        if(nums[mid]==target){
            right=mid;
        }else if(nums[mid]<target){
            left=mid+1;
        }else{
            right=mid-1;
        }
    }
    if(nums[left]==target){
        return left;
    }
    return -1;
}

寻找右边界,不同于左边,寻找右边界时mid=Math.floor((left+right+1)/2),为了避免死循环,当剩余数组数量是偶数时,会将mid落到偏右边的位置

var searchRight= function(nums,target){
    //[]区间
    let left=0,right=nums.length-1;
    while(left<right){
        //为了避免死循环,当剩余数组数量是偶数时,会将mid落到偏右边的位置
        let mid=Math.floor((left+right+1)/2);
        if(nums[mid]==target){
            left=mid;
        }else if(nums[mid]<target){
            left=mid+1;
        }else{
            right=mid-1;
        }
    }
    if(nums[left]==target){
        return left;
    }
    return -1;
}

整体代码如下

 //二分查找,左闭右闭区间
 //寻找第一个等于target的位置leftIx以及
 //第一个大于target的位置

var searchLeft= function(nums,target){
    //[]区间
    let left=0,right=nums.length-1;
    while(left<right){
        let mid=Math.floor((left+right)/2);
        if(nums[mid]==target){
            right=mid;
        }else if(nums[mid]<target){
            left=mid+1;
        }else{
            right=mid-1;
        }
    }
    if(nums[left]==target){
        return left;
    }
    return -1;
}
var searchRight= function(nums,target){
    //[]区间
    let left=0,right=nums.length-1;
    while(left<right){
        //为了避免死循环,当剩余数组数量是偶数时,会将mid落到偏右边的位置
        let mid=Math.floor((left+right+1)/2);
        if(nums[mid]==target){
            left=mid;
        }else if(nums[mid]<target){
            left=mid+1;
        }else{
            right=mid-1;
        }
    }
    if(nums[left]==target){
        return left;
    }
    return -1;
}

var searchRange = function(nums, target) {
    let leftIx=searchLeft(nums,target);
    let rightIx=searchRight(nums,target);
    if(leftIx==-1){
        return [-1,-1]
    }
    return [leftIx,rightIx]
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值