34.Find First and Last Position of Element in Sorted Array

给定一个升序排列的数组,以及一个整数,查找这个整数在数组中出现的起始、终止下标。没找到就返回 [-1,-1]。要求O(log⁡n)时间复杂度。

Input: nums = [5,7,7,8,8,10], target = 8
Output: [3,4]

思路:
  运用二分查找,当找到与目标相等的下标时,停下来,分别找左边的起始点右边的终止点。而左边要求: nums[mid] == target && nums[mid-1] != target,或者 mid = =left;而右边终止点要求:nums[mid] == target &&nums[mid+1] != target, 或者 mid==right.所以,另外写一个函数,用startOrEnd = 1 / -1来区别是找起始点还是终止点。
  当startOrEnd = 1 时, mid - startOrEnd = mid-1;当 = -1时,mid - startOrEnd = mid+1.

class Solution {
public:
    vector<int> searchRange(vector<int>& nums, int target) {
        int n = nums.size(), l = 0, r = n - 1, mid = 0;
        int start = -1, end = -1;
        while (l <= r) {
            mid = (l + r) / 2;
            if (nums[mid] == target) {
                start = searchPosition(nums, l, mid, target, 1);//起始点
                end = searchPosition(nums, mid, r, target, -1);//终止点
                return { start,end };
            }
            else if (nums[mid] > target) r = mid - 1;
            else l = mid + 1;
        }
        return { start,end };
    }

    int searchPosition(vector<int>& nums, int left, int right, int target, int startOrEnd) {
        while (left <= right) {
            int mid = (left + right) / 2;
            if (nums[mid] == target) {
                if (mid == left && startOrEnd == 1) return mid;//左边mid = left
                else if (mid == right && startOrEnd == -1) return mid;//右边mid = right
                if (nums[mid - startOrEnd] != target) return mid;
                if (startOrEnd == 1) right = mid - 1;//否则,继续循环
                else left = mid + 1;
            }
            else if (nums[mid] > target) right = mid - 1;
            else left = mid + 1;
        }
        return -1;
    }
};

 

Java 版:

  • 对于已经排好序的数组,首先想到的就是二分查找;
  • 当找到与目标值相等的下标时,停下来,分别找左边的起始点,右边的终止点;
  • 左指针要求: nums[mid] == target && nums[mid-1] != target;
  • 右指针要求:nums[mid] == target && nums[mid+1] != target。
  • 所以,分别用两个函数,得到左指针、右指针的位置。

class Solution {
    public int[] searchRange(int[] nums, int target) {
        int l = serchLeftIndx(nums, target);
        int r = serchRightIndx(nums, target);
        if(l > r) return new int[]{-1, -1}; //没有找到结果
        return new int[]{l,r};
    }
    public int serchLeftIndx(int[] nums, int target){ //得到左指针位置
        int mid = 0, l = 0, r = nums.length - 1;
        while(l <= r){
            mid = (l + r) / 2;
            if(nums[mid] >= target) r = mid - 1;
            else l = mid + 1;
        }
        return l;
    }
    public int serchRightIndx(int[] nums, int target){ //得到右指针位置
        int mid = 0, l = 0, r = nums.length - 1;
        while( l <= r){
            mid = (l + r) / 2;
            if(nums[mid] <= target) l = mid + 1;
            else r = mid - 1;
        }
        return l - 1;
    }
}

 

posted @ 2020-05-21 16:03  星海寻梦233  阅读(120)  评论(0编辑  收藏  举报