Leetcode 33. 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.
解题思路:
高频题。
binary search 的本质就是每次扔掉一部分。只要确定答案不在这一部分,就扔掉这一部分。
与Leetcode Find Minimum in Rotated Sorted Array Leetcode Find Minimum in Rotated Sorted Array II 是一个类型的题目。
用binary search,Complexity: O(logn), 关键点在于每次要能判断出target位于左半还是右半序列。解这题得先在纸上写几个rotated sorted array的例子出来找下规律。Rotated sorted array根据旋转得多少有两种情况:
原数组:0 1 2 4 5 6 7
情况1: 6 7 0 1 2 4 5 起始元素0在中间元素的左边
情况2: 2 4 5 6 7 0 1 起始元素0在中间元素的右边
两种情况都有半边是完全sorted的。根据这半边,当target != A[mid]时,可以分情况判断:
当A[mid] < A[end] < A[start]:情况1,右半序列A[mid+1 : end] sorted
A[mid] < target <= A[end], 右半序列,否则为左半序列。
当A[mid] > A[start] > A[end]:情况2,左半序列A[start : mid-1] sorted
A[start] <= target < A[mid], 左半序列,否则为右半序列
Base case:当start + 1 = end时
假设 2 4:
A[mid] = A[start] = 2 < A[end],A[mid] < target <= A[end] 右半序列,否则左半序列
假设 4 2:
A[mid] = A[start ] = 4 > A[end], A[start] <= target < A[mid] 左半序列,否则右半序列
加入base case的情况,最终总结的规律是:
A[mid] = target, 返回mid,否则
(1) A[mid] < A[end]: A[mid+1 : end] sorted
A[mid] < target <= A[end] 右半,否则左半。
(2) A[mid] > A[end] : A[start : mid-1] sorted
A[start] <= target < A[mid] 左半,否则右半。
方法一: recursive, 方法二: iterative, 对recursive 的简单改写。
Java code :
1. recursive
public class Solution { public int search(int[] nums, int target) { return binarySearch(nums, 0, nums.length-1, target); } public int binarySearch(int[] nums, int left, int right, int target){ if(left > right) { return -1; } int mid = left + (right - left)/2; if(target == nums[mid]){ return mid; } if(nums[mid] < nums[right]) { //right half sorted if(nums[mid] < target && target <= nums[right]){ return binarySearch(nums, mid+1, right, target); }else { return binarySearch(nums, left, mid-1, target); } }else { //left half sorted if(nums[left] <= target && target < nums[mid]){ return binarySearch(nums, left, mid-1, target); }else{ return binarySearch(nums, mid+1, right, target); } } } }
2. iterative
public class Solution { public int search(int[] nums, int target) { int left = 0, right = nums.length-1; while(left <= right){ int mid = left + (right - left)/2; if(nums[mid] == target) { return mid; } if(nums[mid] < nums[right]) { //right half sorted if(target > nums[mid] && target <= nums[right]){ left = mid+1; }else{ right = mid-1; } }else { //left half sorted if(target >= nums[left] && target < nums[mid]){ right = mid-1; }else { left = mid+1; } } } return -1; } }
3. 九章算法答案,画图解决,理解binary search 的本质,就是每次扔掉一部分。2016.01.15
public class Solution { public int search(int[] nums, int target) { if(nums == null || nums.length == 0) { return -1; } int start = 0, end = nums.length-1; int mid; while(start + 1 < end){ mid = start + (end - start) / 2; if(nums[mid] == target) { return mid; } if(nums[start] < nums[mid]){ if(nums[start] <= target && target <= nums[mid]){ end = mid; } else { start = mid; } } else { if(nums[mid] <= target && target <= nums[end]){ start = mid; } else { end = mid; } } }//while if(nums[start] == target){ return start; } if(nums[end] == target){ return end; } return -1; } }
Reference:
1. http://bangbingsyb.blogspot.com/2014/11/leetcode-search-in-rotated-sorted-array.html
2. http://www.programcreek.com/2014/06/leetcode-search-in-rotated-sorted-array-java/