http://oj.leetcode.com/problems/search-in-rotated-sorted-array/
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.
思路:
因为没有重复元素,所以情况变得比较简单,要么递增,要么就是如下情况:A[0] < A[n],同时存在一点A[k] > A[k - 1]并且A[k] > A[k + 1]。
/ (k) / / / (start) / (end) / / (k + 1)
对于A[start] < A[end]的情况很简单,直接二分法搞定。对于后一种情况,先找到k点,然后确定target在A[start]到A[k]的区间还是A[k + 1]到A[end]的区间,因为每个区间都是递增的,也可以用二分法搞定。整个题目的难点在于如何用二分法找到k点。
- 如果区间只有一个元素就直接返回。
- 如果A[end] > A[start],说明是个递增序列,返回end。
- 如果A[start] > A[start + 1],返回start。
- 令mid等于(start + end) / 2。
- 如果A[mid] < A[end],说明mid在k + 1到end的区间,那么k就在start在mid - 1的区间,递归调用,令start不变,end等于mid - 1。
- 如果A[mid] > A[start],说明k在mid到end的区间,递归调用,令start等于mid,end不变。
1 class Solution { 2 public: 3 int findPivot(int A[], int start, int end) { 4 if (start == end) { 5 return start; 6 } 7 else if (A[end] > A[start]) { 8 return end; 9 } 10 else if (A[start] > A[start + 1]) { 11 return start; 12 } 13 14 int mid = (start + end) / 2; 15 16 if (A[mid] < A[end]) { 17 return findPivot(A, start, mid - 1); 18 } 19 else if (A[mid] > A[start]) { 20 return findPivot(A, mid, end); 21 } 22 } 23 24 int binarySearch(int A[], int start, int end, int target) { 25 while (start <= end) { 26 int mid = (start + end) / 2; 27 28 if (A[mid] == target) { 29 return mid; 30 } 31 else if (A[mid] < target) { 32 start = mid + 1; 33 } 34 else { 35 end = mid - 1; 36 } 37 } 38 39 return -1; 40 } 41 42 int search(int A[], int n, int target) { 43 int pivot = findPivot(A, 0, n - 1); 44 45 return (target >= A[0]) ? binarySearch(A, 0, pivot, target) : binarySearch(A, pivot + 1, n - 1, target); 46 } 47 };