题目:
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.
链接: http://leetcode.com/problems/search-in-rotated-sorted-array-ii/
题解:
平移过的数组查找数字。依然是使用二分查找,不过有了duplicate所以判断的条件更多更复杂。
Time Complexity - O(n), Space Complexity - O(1)。
public class Solution { public boolean search(int[] nums, int target) { if(nums == null || nums.length == 0) return false; int lo = 0, hi = nums.length - 1; while(lo <= hi) { int mid = lo + (hi - lo) / 2; if(target < nums[mid]) { if(nums[mid] < nums[hi]) { // right half sorted hi = mid - 1; } else if(nums[mid] > nums[hi]) { //left half sorted if(target < nums[lo]) { lo = mid + 1; //target at right half } else { hi = mid - 1; //target at left half } } else { // nums[mid] == nums[hi], cannot tell hi--; } } else if (target > nums[mid]) { if(nums[lo] < nums[mid]) { //left half sorted lo = mid + 1; } else if(nums[lo] > nums[mid]) { // right half sorted if(target > nums[hi]) hi = mid - 1; //target at left half else lo = mid + 1; //target at right half } else { // nums[mid] == nums[hi], cannot tell lo++; } } else // nums[mid] == target, found return true; } return false; } }
二刷:
还是使用二分法来完成搜索。这里不同的地方是,假如nums[mid]等于一个端点的时候,假如是左端点,那么我们不能判断出哪一边是排序的,只能lo++。否则,我们可以通过比较判断出左边或者右边是排序的,从而使用二分查找。
Java:
Time Complextiy - O(n), Space Complexity - O(1)
public class Solution { public boolean search(int[] nums, int target) { if (nums == null || nums.length == 0) { return false; } int lo = 0, hi = nums.length - 1; while (lo <= hi) { int mid = lo + (hi - lo) / 2; if (nums[mid] == target) { return true; } if (nums[lo] < nums[mid]) { if (nums[lo] <= target && target < nums[mid]) { hi = mid - 1; } else { lo = mid + 1; } } else if (nums[lo] > nums[mid]) { if (nums[mid] < target && target <= nums[hi]) { lo = mid + 1; } else { hi = mid - 1; } } else { lo++; } } return false; } }
2/6/2016
题外话:
国内今天已经是29号,除夕了。现在我一个人在美帝的家里,中午刚上完课,下午也参加了一个tech talk。依然是平实的一天,就是觉得有点蛋疼, 该春节回家陪陪爸妈的。 我打算明天给自己放假一天,好好看会电视,然后去H-Mart买桶炸鸡吃掉。
三刷:
其实29号那天并没有吃炸鸡。
注意比较的都是nums[lo]和nums[mid]。我们在比较晚nums[lo]和nums[mid]之后, 再假定一边有序,一边无序的情况。假如nums[lo] == nums[lo],我们不能二分,只能增加lo来继续下一次判断。
Java:
public class Solution { public boolean search(int[] nums, int target) { if (nums == null || nums.length == 0) return false; int lo = 0, hi = nums.length - 1; while (lo <= hi) { int mid = lo + (hi - lo) / 2; if (nums[mid] == target) return true; if (nums[lo] < nums[mid]) { if (target >= nums[lo] && target < nums[mid]) hi = mid - 1; else lo = mid + 1; } else if (nums[lo] > nums[mid]) { if (target > nums[mid] && target <= nums[hi]) lo = mid + 1; else hi = mid - 1; } else { lo++; } } return false; } }
Reference:
https://leetcode.com/discuss/223/when-there-are-duplicates-the-worst-case-is-could-we-do-better