leetcode刷题-Array#4

33. Search in Rotated Sorted Array

Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand.

(i.e., [0,1,2,4,5,6,7] might become [4,5,6,7,0,1,2]).

You are given a target value to search. If found in the array return its index, otherwise return -1.

You may assume no duplicate exists in the array.

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

Example 1:

Input: nums = [4,5,6,7,0,1,2], target = 0
Output: 4

Example 2:

Input: nums = [4,5,6,7,0,1,2], target = 3
Output: -1
  • 思路:题目说了复杂度要在O(logn),所以一定也是二分搜索。问题就是旋转之后怎么处理这个问题?
    • 正常二分中,l < mid < r。但是经过旋转之后,mid和左右的大小是不确定的。mid和target比较之后,要往哪个区间走?如果大了,肯定往小的区间走,如果小了,肯定往大的区间走。具体向右还是向左,需要比较 l 和 r 的值之后再做决定。后来发现这个思路不太对。
    • 旋转之后有两个区间,mid落在左边或者右边。
      • mid落在左边区间:mid > r
        • 如果target在左边 [l, mid - 1]这个单调区间之中,则继续在这个区间搜索,
        • 否则在 [mid + 1, r] 这个区间搜索
      • mid落在右边区间:mid < l
        • 如果target在右边 [mid + 1, r ]这个单调区间,则继续在这个区间搜索
        • 否则在 [l, mid - 1] 搜索
      • 否则这个区间没有旋转,是个单调区间,直接用二分就好
class Solution {
public:
    int search(vector<int>& nums, int target) {
        int l = 0, r = nums.size() - 1;
        while(l <= r) {
            int mid = (l + r) / 2;
            if(target == nums[mid])
                return mid;
            // in left
            if(nums[mid] > nums[r]) {
                if(nums[l] <= target && target < nums[mid]) {
                    r = mid - 1;
                } else {
                    l = mid + 1;
                }
            } 
            // in right
            else if(nums[mid] < nums[l]) {
                if(nums[mid] < target && target <= nums[r]) {
                    l = mid + 1;
                } else {
                    r = mid - 1;
                }
            }
            // no problem
            else {
                if(target > nums[mid])
                    l = mid + 1;
                else
                    r = mid - 1;
            }
        }
        return -1;
    }
};

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

Given an array of integers nums 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 1:

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

Example 2:

Input: nums = [5,7,7,8,8,10], target = 6
Output: [-1,-1]
  • 思路:
    • start:
      • 左指针只在mid<target这种确定情况下才修改
      • mid > target : r = mid
      • mid = target : r = mid
      • mid < target : l = mid + 1
    • end:
      • 右指针只在mid>target这种确定情况下才修改
      • mid > target : r = mid - 1
      • mid = target : l = mid
      • mid < target : l = mid
  • 有个比较tricky的地方,在代码里说明了
class Solution {
public:
    vector<int> searchRange(vector<int>& nums, int target) {
        int l = 0, r = nums.size() - 1;
        vector<int> ret(2, -1);
        if(nums.size() == 0)
            return ret;
        // search for left
        while(l < r) {
            int mid = (l + r) / 2;
            if(nums[mid] < target)
                l = mid + 1;
            else
                r = mid;
        }
        if(nums[l] != target) return ret;
        ret[0] = l;
        
        r = nums.size() - 1;
        // search for right
        while(l < r) {
            int mid = (l + r) / 2 + 1; // 让mid偏向右边
            if(nums[mid] > target)
                r = mid - 1;
            else
                l = mid; // mid会一直移动,不会死循环
        }
        ret[1] = r;
        return ret;
    }
};
发布了44 篇原创文章 · 获赞 0 · 访问量 986

猜你喜欢

转载自blog.csdn.net/weixin_37748689/article/details/96622208