leetcode:34. Search for a Range

来源:互联网 发布:风管机品牌知乎 编辑:程序博客网 时间:2024/06/05 05:32

描述

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

思路

这里的思路肯定是二分查找,两个思路,一个是利用递归实现二分查找,第二个是使用循环做二分查找。我实现了使用循环进行二分查找。
首先使用正常的二分查找,找到target,找到target之后,再从这个位置往上往下分别查找上届和下届。

代码

class Solution {public:    vector<int> searchRange(vector<int>& nums, int target) {        vector<int> result(2);        result[0] = -1;        result[1] = -1;        if(nums.empty())            return result;        int low = 0, high = nums.size() - 1, middle = (low + high) / 2;        int leftHigh = middle, rightLow = middle;        while(low <= high){            if(nums[middle] != target){                middle = (low + high) / 2;                if(nums[middle] > target){                    high = middle - 1;                }                else if(nums[middle] < target){                    low = middle + 1;                }                else{                    leftHigh = middle;                    rightLow = middle;                }            }            else{                while(low <= leftHigh){                    cout << "left" << endl;                    if(nums[low] == target){                        result[0] = low;                        break;                    }                    int mid = (low + leftHigh) / 2;                    if(nums[mid] == target){                        leftHigh = mid - 1;                        if(nums[leftHigh] != target){                            result[0] = mid;                            break;                        }                    }                    else if(nums[mid] < target){                        low = mid+1;                        if(nums[low] == target){                            result[0] = low;                            break;                        }                    }                }                while(rightLow <= high){                    if(nums[high] == target){                        result[1] = high;                        break;                    }                    int mid = (rightLow + high) / 2;                    if(nums[mid] == target){                        rightLow = mid + 1;                        if(nums[rightLow] != target){                            result[1] = mid;                            break;                        }                    }                    else if(nums[mid] > target){                        high = mid-1;                        if(nums[high] == target){                            result[1] = high;                            break;                        }                    }                }                break;            }        }        return result;    }};

结果

这里写图片描述

他山之玉

C++ O(n) solutioin

vector<int> searchRange(vector<int>& nums, int target) {    int start = 0, end = nums.size(), mid, left, right;    while (start < end) {        mid = (start + end) / 2;        if (nums[mid] >= target)            end = mid;        else            start = mid + 1;    }    left = start;    start = 0, end = nums.size();    while (start < end) {        mid = (start + end) / 2;        if (nums[mid] > target)            end = mid;        else            start = mid + 1;    }    right = start;    return left == right ? vector<int> {-1,-1} : vector<int> {left,right-1};}

这个思路是做两次二分查找,一次往上查找,一次往下查找。

Java O(n) solution

public int[] searchRange(int[] nums, int target) {    int idx = Arrays.binarySearch(nums, target);    if (idx < 0) {        return new int[]{-1, -1};    }    int left = idx - 1, right = idx + 1;    while (left >= 0 && nums[left] == nums[idx])        left--;    while (right < nums.length && nums[right] == nums[idx])        right++;    return new int[]{left + 1, right - 1};}

这个思路是先用算法库中的二分查找,找到target,然后在从target出发,往上往下遍历查找。
python O(n) solution

class Solution(object):    def get_lower_bound(self, nums, target):        low, high = 0, len(nums)-1        ans = -1        while low <= high:            mid = low + (high-low)//2            if nums[mid] == target:                ans = mid                high = mid-1            elif nums[mid] < target:                low = mid + 1            else:                high = mid - 1        return ans    def get_upper_bound(self, nums, target):        low, high = 0, len(nums)-1        ans = -1        while low <= high:            mid = low + (high-low)//2            if nums[mid] == target:                ans = mid                low = mid+1            elif nums[mid] < target:                low = mid + 1            else:                high = mid - 1        return ans    def searchRange(self, nums, target):        """        :type nums: List[int]        :type target: int        :rtype: List[int]        """        lower_bound = self.get_lower_bound(nums, target)        upper_bound = self.get_upper_bound(nums, target)        return [lower_bound, upper_bound]    

思路仍然是做两次二分查找。

反思

算法在纸上先走一遍,走通了再写代码。

0 0
原创粉丝点击