Search in Rotated Sorted Array

xiaoxiao2021-02-28  103

/* Description: 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 */

方法一

/* Parse:二分查找,难度主要在于左右边界的确定。 假设有一个排序的按未知的旋转轴旋转的数组(比如,0 1 2 4 5 6 7 可能成为4 5 6 7 0 1 2)。 给定一个目标值进行搜索,如果在数组中找到目标值返回数组中的索引位置,否则返回-1。 给出[4, 5, 1, 2, 3]和target=1,返回 2 给出[4, 5, 1, 2, 3]和target=0,返回 -1 note:没有重复的元素是重要信息 */ // LeetCode, Search in Rotated Sorted Array // 时间复杂度 O(log n)空间复杂度(1) #include<iostream> #include<vector> using namespace std; class Solution { public: int search(const vector<int>& nums, int target) { int first = 0, last = nums.size(); while (first != last) { const int mid = first + (last - first) / 2; if (nums[mid] == target) return mid; if (nums[first] <= nums[mid]) { if (nums[first] <= target && target < nums[mid]) last = mid; else first = mid + 1; } else { if (nums[mid] < target && target <= nums[last-1]) first = mid + 1; else last = mid; } } return -1; } }; int main(){ Solution a; vector<int> nums; nums.push_back(0); nums.push_back(1); nums.push_back(2); nums.push_back(4); nums.push_back(5); nums.push_back(6); nums.push_back(7); int b=a.search(nums,7); cout<<b; return 0; }

方法二

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; } };

思路:二分查找

难点在于确定往数组的哪一半段继续二分查找 设起点、中间点、终点分别为 start、middle、end (採用前闭后开的区间表示方法 假设target = A[middle] return middle 假设A[middle] >= A[start],则[start,middle)单调递增 1.假设target < A[middle] && target >= A[start],则 end = middle 2.start = middle + 1, otherwise 假设A[middle] < A[start]。则[middle,end)单调递增 1.假设target > A[middle] && target <= A[end - 1],则 start = middle + 1 2.end = middle, otherwise


Explanation

My solutions use binary search guided by the following thoughts:

Remember the array is sorted, except it might drop at one point.

If nums[0] <= nums[i], then nums[0..i] is sorted (in case of "==" it's just one element, and in case of "<" there must be a drop elsewhere). So we should keep searching in nums[0..i] if the target lies in this sorted range, i.e., if nums[0] <= target <= nums[i]. If nums[i] < nums[0], then nums[0..i] contains a drop, and thus nums[i+1..end] is sorted and lies strictly between nums[i] and nums[0]. So we should keep searching in nums[0..i] if the target doesn't lie strictly between them, i.e., if target <= nums[i] < nums[0] or nums[i] < nums[0] <= target

Those three cases look cyclic:

nums[0] <= target <= nums[i] target <= nums[i] < nums[0] nums[i] < nums[0] <= target

So I have the three checks (nums[0] <= target), (target <= nums[i]) and (nums[i] < nums[0]), and I want to know whether exactly two of them are true. They can’t all be true or all be false (check it), so I just need to distinguish between “two true” and “one true”. Parity is enough for that, so instead of adding them I xor them, which is a bit shorter and particularly helpful in Java and Ruby, because those don’t let me add booleans but do let me xor them.

(Actually while developing this I thought of permutations of nums[0], target and nums[i] and the permutation parity and saw those three checks as representing inversions, but I had trouble putting that into words and now find the above explanation much better. But it helped me get there, so I wanted to mention it here.)


【转发1】

转载请注明原文地址: https://www.6miu.com/read-43794.html

最新回复(0)