LeetCode 33,81. Search in Rotated Sorted Array i, ii

来源:互联网 发布:python的布尔值 编辑:程序博客网 时间:2024/06/05 22:32

1. 题目描述

33

Suppose a sorted array 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.

81

Follow up for “Search in Rotated Sorted Array”:
What if duplicates are allowed?

Would this affect the run-time complexity? How and why?

Write a function to determine if a given target is in the array.

2. 解题思路

这是一个有序数组, 所以我们可以尝试使用二分的思路去解决这个问题, 不过需要注意一个问题,使用二分法的时候, 边界问题的判断。 这里由于不太记得住二分法究竟怎么写了, 于是在自己的代码中加了一个补丁, 特别判断一下 start == stop - 1 的情形

而对于 81 题, 由于允许重复, 我们只需要对有重复部分区域采用遍历即可。

3. code

3.1 code 33

class Solution {public:    int search(vector<int>& nums, int target) {        return helper(nums, 0, nums.size() - 1, target);    }private:    // x -->  [start, stop];    int helper(vector<int>& nums, int start, int stop, int target){        int res = -1;        while (start <= stop){            int mid = start + ((stop - start) >> 1);            if (nums[mid] == target)                return mid;            if (start == stop)                break;            // 我是补丁            if (start == stop - 1){                if (nums[stop] == target)                    return stop;                break;            }            if (nums[start] < nums[mid]){                if (nums[start] <= target && nums[mid] > target)                    stop = mid - 1;                else                    start = mid + 1;            }            else{                if (nums[mid] < target && nums[stop] >= target)                    start = mid + 1;                else                    stop = mid - 1;            }        }        return res;    }};

3.2 81 code

class Solution {public:    bool search(vector<int>& nums, int target) {        return helper(nums, 0, nums.size() - 1, target) >= 0;    }private:    // x -->  [start, stop];    int helper(vector<int>& nums, int start, int stop, int target){        int res = -1;        while (start <= stop){            int mid = start + ((stop - start) >> 1);            if (nums[mid] == target)                return mid;            if (start == stop)                break;            // 我是补丁            if (start == stop - 1){                if (nums[stop] == target)                    return stop;                break;            }            // 遍历搜索            if (nums[start] == nums[mid] || nums[stop] == nums[mid] || nums[start] == nums[stop]){                for (int i = start; i != stop + 1; i++){                    if (nums[i] == target)                        return i;                }                return -1;            }            if (nums[start] < nums[mid]){                if (nums[start] <= target && nums[mid] > target)                    stop = mid - 1;                else                    start = mid + 1;            }            else{                if (nums[mid] < target && nums[stop] >= target)                    start = mid + 1;                else                    stop = mid - 1;            }        }        return res;    }};

4. 大神解法

4.1 33 demo1 先修复旋转数组, 再查找

这段代码, 主要是通过先利用二分查找, 找到最小值的位置, 然后根据这个最小值的位置, 可以推算出该旋转数组和该数组之间的转化关系, 利用二分查找即可, what a brilliant solution!!!

class Solution {public:    int search(int A[], int n, int target) {        int lo=0,hi=n-1;        // find the index of the smallest value using binary search.        // Loop will terminate since mid < hi, and lo or hi will shrink by at least 1.        // Proof by contradiction that mid < hi: if mid==hi, then lo==hi and loop would have been terminated.        while(lo<hi){            int mid=(lo+hi)/2;            if(A[mid]>A[hi]) lo=mid+1;            else hi=mid;        }        // lo==hi is the index of the smallest value and also the number of places rotated.        int rot=lo;        lo=0;hi=n-1;        // The usual binary search and accounting for rotation.        while(lo<=hi){            int mid=(lo+hi)/2;            int realmid=(mid+rot)%n;            if(A[realmid]==target)return realmid;            if(A[realmid]<target)lo=mid+1;            else hi=mid-1;        }        return -1;    }};

4.2 33 demo2 思路和我们的一致

public class Solution {public int search(int[] A, int target) {    int lo = 0;    int hi = A.length - 1;    while (lo < hi) {        int mid = (lo + hi) / 2;        if (A[mid] == target) return mid;        if (A[lo] <= A[mid]) {            if (target >= A[lo] && target < A[mid]) {                hi = mid - 1;            } else {                lo = mid + 1;            }        } else {            if (target > A[mid] && target <= A[hi]) {                lo = mid + 1;            } else {                hi = mid - 1;            }        }    }    return A[lo] == target ? lo : -1;}}

4.3 81 demo

由于当发生重复的时候, A[m] == A[l], 可以将 l++, 因为这个l 的值会在后面的内容中再次出现的。。。

bool search(int A[], int n, int key) {    int l = 0, r = n - 1;    while (l <= r) {        int m = l + (r - l)/2;        if (A[m] == key) return true; //return m in Search in Rotated Array I        if (A[l] < A[m]) { //left half is sorted            if (A[l] <= key && key < A[m])                r = m - 1;            else                l = m + 1;        } else if (A[l] > A[m]) { //right half is sorted            if (A[m] < key && key <= A[r])                l = m + 1;            else                r = m - 1;        } else l++;    }    return false;}
0 0
原创粉丝点击