33. Search rotated sorted array

Suppose an array sorted in ascending order is rotated at some point unknown in advance.

(for example, an array  [0,1,2,4,5,6,7] might become  [4,5,6,7,0,1,2] ).

Search for a given target value and return its index if the target value exists in the array, otherwise return it  -1 .

You can assume that there are no duplicate elements in the array.

The time complexity of your algorithm must be  O (log  n ) level.

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

Idea: Two points twice.

1. For the first time, find the position of the largest value in the array:

(1) If it is a monotonically increasing interval, the maximum value is at the right endpoint.

(2) If it is an interval with a rotation point: if the midpoint value is smaller than the left endpoint value, the maximum value is in the left half, and if the midpoint value is larger than the left endpoint value, the maximum value is in the right half. This process is repeated until the maximum position is found.

2. Find the position of the target value for the second time: If the size of the target value is between the left endpoint and the rotation point value, then perform a binary search on the incremental interval of the left half of the rotation point to find the target value. If the size of the target value is between the rotation point value and the right endpoint value, perform a binary search on the incrementing interval of the right half of the rotation point until the target value is found. Returns -1 if not found.

class Solution {
public:
int search(vector<int>& nums, int target) {
	if (nums.empty()) return -1;
	int l = 0, r = nums.size() - 1, l1, r1, flag = -1; //flag records the coordinates of the maximum value in the array
	while (l < r){
		if (nums[l] <= nums[r]) break;//Monotonically increasing interval, jump out of the loop directly, the right endpoint r is the maximum index
		else{ //The interval with the rotation point, wait until the end of the loop, l is the maximum index
			int mid = l + (r - l) / 2;
			if (nums[mid] > nums[l])  
				l = mid;
			else  if (nums[mid] <= nums[l])
				r = mid-1;
		}
	}
	flag = (l < r ? r : l);  
	if (target >= nums[0]){ //The target value falls in the left half increasing interval
		l1 = 0;
		r1 = flag;
	}
	if (target < nums[0]){//The target value falls in the right half increasing interval
		l1 = flag + 1;
		r1 = nums.size() - 1;
	}
	while (l1 <= r1){//Use binary search to find the target value in the increasing interval
		int mid1 = l1 + (r1 - l1) / 2;
		if (nums[mid1] > target)
			r1 = mid1 - 1;
		if (nums[mid1] < target)
			l1 = mid1 + 1;
		if (nums[mid1] == target)
			return mid1;   
	}
	return -1;//If not found, return -1
}
};

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324617314&siteId=291194637