34. Search for a Range

来源:互联网 发布:杜老师的c编程密码 编辑:程序博客网 时间:2024/06/05 02:27

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].

For example,
Given [5, 7, 7, 8, 8, 10] and target value 8,
return [3, 4].

题目中说明是排序数组,则肯定要用到二分查找啊,不然不能保证O(log n),所以,此题可以理解为分别找到target在数组中的low和high边界;

int search_high(vector<int>& nums, int target, int low, int high){    if (low > high)return -1;    int mid = low + (high - low) / 2;    if (nums[mid] > target)high = mid - 1;    else if (nums[mid] < target)low = mid + 1;    else{        if (mid == high || (mid < high && nums[mid + 1] != target))return mid;        else low = mid + 1;    }    return search_high(nums, target, low, high);}int search_low(vector<int>& nums, int target, int low,int high){    if (low > high)return -1;    int mid = low + (high - low) / 2;    if (nums[mid] > target)high = mid - 1;    else if (nums[mid] < target)low = mid + 1;    else {        if (mid == 0 || (mid > 0 && nums[mid - 1] != target))return mid;        else high = mid - 1;    }    return search_low(nums, target, low, high);}vector<int> searchRange(vector<int>& nums, int target) {    if (nums.size() == 0 || nums[0] > target || nums[nums.size() - 1] < target)return vector<int>({ -1, -1 });    int low = search_low(nums, target, 0, nums.size() - 1);    int high = search_high(nums, target, 0, nums.size() - 1);    vector<int> res = { low, high };    return res;}

思路2:不用递归,直接循环

class Solution {public:    vector<int> searchRange(vector<int>& nums, int target) {        const int begin = lower_bound(nums, target);        const int end = upper_bound(nums, target);        if (begin < nums.size() && nums[begin] == target) {            return{ begin, end - 1 };        }        return{ -1, -1 };    }private:    int lower_bound(vector<int>& nums, int target) {        int left = 0;        int right = nums.size();        while (left < right) {            const auto mid = left + (right - left) / 2;            if (nums[mid] >= target)                right = mid;            else                left = mid + 1;        }        return left;    }    int upper_bound(vector<int>& nums, int target) { // find the first larger than target        int left = 0;        int right = nums.size();        while (left < right) {            const auto mid = left + (right - left) / 2;            if (nums[mid] > target)                right = mid;            else                left = mid + 1;        }        return left;    }};