[Leetcode] Search for a Range

Search for a Range 题解

题目来源:https://leetcode.com/problems/search-for-a-range/description/


Description

Given an array of integers sorted in ascending order, find the starting and ending position of a given target value.

Your algorithm's runtime complexity must be in the order of O(log n).

If the target is not found in the array, return [-1, -1].

Example

For example,

Given [5, 7, 7, 8, 8, 10] and target value 8,

return [3, 4].

Solution

class Solution {
public:
    vector<int> searchRange(vector<int>& nums, int target) {
        vector<int> res(2, -1);
        if (nums.empty())
            return res;
        int size = nums.size();
        int low = 0, high = size - 1, mid;
        while (low <= high) {
            if (target < nums[low] || target > nums[high])
                return res;
            mid = (low + high) / 2;
            if (target == nums[mid])
                break;
            if (target < nums[mid])
                high = mid;
            if (target > nums[mid]) {
                if (mid + 1 <= size - 1)
                    low = mid + 1;
                else
                    return res;
            }
        }
        auto temp = mid;
        while (temp - 1 >= 0 && nums[temp - 1] == target)
            temp--;
        res[0] = temp;
        temp = mid;
        while (temp + 1 <= size - 1 && nums[temp + 1] == target)
            temp++;
        res[1] = temp;
        return res;
    }
};

解题描述

这道题题意是,在一个排好序的数组中查找一个目标数字所在的区间。用到的算法首选二分查找,上面是我一开始的解法,不过时间复杂度较高,二分查找只是用于找到一个目标数字的位置,然后再向两边探测边界。

看了评论区的解答后改进了算法,将查找分成了二分查找下界和上界两步:

class Solution {
public:
    vector<int> searchRange(vector<int>& nums, int target) {
        vector<int> res(2, -1);
        if (nums.empty())
            return res;
        int size = nums.size();
        int low = 0, high = size - 1, mid;
        while (low < high) {
            mid = (low + high) / 2;
            if (target > nums[mid])
                low = mid + 1; // 向右逼近,以找到下界
            else
                high = mid;
        }
        // 判断下界是否是目标元素所在,不是的话说明找不到目标元素
        if (nums[low] != target)
            return res;
        res[0] = low;
        high = size - 1;
        while (low < high) {
            mid = (low + high) / 2 + 1; // 多+1,让中间位置偏向右边,防止陷入死循环
            if (target < nums[mid])
                high = mid - 1; // 向左逼近,以找到上界
            else
                low = mid;
        }
        res[1] = high;

        return res;
    }
};
原文地址:https://www.cnblogs.com/yanhewu/p/8408762.html