34. Find First and Last Position of Element in Sorted Array(100%)

AC 3ms faster than 100% java.

1 . 我的思路

先用二分查找到target或者target不存在。

然后以此target为中心向左向右寻找边界。

AC代码如下:

class Solution {
    public int[] searchRange(int[] nums, int target) {
        int[] ans={-1,-1};
        if(nums==null||nums.length==0)
            return ans;
        int i=0,j=nums.length;
        int mid=-1;
        while(i<=j&&j>=0&&i<nums.length){
            mid=(i+j)/2;
            if(nums[mid]==target)
                break;
            else if(nums[mid]>target)
                j=mid-1;
            else if(nums[mid]<target)
                i=mid+1;
        }
        if(mid!=-1&&nums[mid]==target){
            int left=mid,right=mid;
            while(left>=0&&nums[left]==target)
                left--;
            while(right<nums.length&&nums[right]==target)
                right++;
            if(nums[left+1]==target&&nums[right-1]==target){
                ans[0]=left+1;
                ans[1]=right-1;
            }
        }
        return ans;
    }
}

2. 官方题解

整个算法的工作原理与线性扫描方法非常相似,除了用于查找最左边和最右边索引本身的子程序。

在这里,我们使用一个经过修改的二分搜索来搜索一个排序的数组,只需要做一些细微的调整。

首先,因为我们正在定位包含目标的最左(或最右)索引(而不是返回我们找到目标的真实index),

所以算法不会在找到匹配时立即终止。相反,我们继续搜索,直到lo == hi,并且它们包含一些

可以在其中找到目标的索引。


另一个变化是引入了left参数,它是一个布尔值,指示在target == nums[mid]事件中要做什么;

如果left为真,则在tie上的左子数组上“递归”。否则,我们往右走。为了理解为什么这是正确的,

考虑一下我们在索引i处找到目标的情况,最左边的目标不可能出现在任何大于i的索引处,所以我们

永远不需要考虑正确的子数组。同样的参数也适用于最右边的索引。

class Solution {
    // returns leftmost (or rightmost) index at which `target` should be
    // inserted in sorted array `nums` via binary search.
    private int extremeInsertionIndex(int[] nums, int target, boolean left) {
        int lo = 0;
        int hi = nums.length;

        while (lo < hi) {
            int mid = (lo + hi) / 2;
            if (nums[mid] > target || (left && target == nums[mid])) {
                hi = mid;
            }
            else {
                lo = mid+1;
            }
        }

        return lo;
    }

    public int[] searchRange(int[] nums, int target) {
        int[] targetRange = {-1, -1};

        int leftIdx = extremeInsertionIndex(nums, target, true);

        // assert that `leftIdx` is within the array bounds and that `target`
        // is actually in `nums`.
        if (leftIdx == nums.length || nums[leftIdx] != target) {
            return targetRange;
        }

        targetRange[0] = leftIdx;
        targetRange[1] = extremeInsertionIndex(nums, target, false)-1;

        return targetRange;
    }
}

官方题解链接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值