题目链接:https://leetcode.com/problems/search-in-rotated-sorted-array-ii/
要求在一个被旋转的排序数组中寻找目标值,判断是否存在。应为涉及到二分法,所以可以先看看这一篇关于二分法的bug free模板博客(https://blog.csdn.net/To_be_to_thought/article/details/85373817)。
思路一:使用集合思想,简单粗暴,代码如下:
class Solution {
public boolean search(int[] nums, int target)
{
HashSet<Integer> set=new HashSet();
for(int i=0;i<nums.length;i++)
set.add(nums[i]);
return set.contains(target);
}
}
O(n)的效率当然不堪入目,勉强AC。
思路二:先确定被旋转的索引位置,再用二分法,代码如下:
class Solution {
public boolean search(int[] nums, int target) {
//先找到最小值的索引
if(nums.length==0)
return false;
if(nums.length==1)
return nums[0]==target;
int i=0;
for(;i<nums.length-1;i++)
{
if(nums[i]>nums[i+1])
break;
}
if(i==nums.length-1|| target>=nums[0] && target<=nums[i])
{
int lo=0,hi=i+1;
while(lo<hi)
{
int mid=lo+(hi-lo)/2;
if(nums[mid]<target)
lo=mid+1;
else
hi=mid;
}
return lo<nums.length && nums[lo]==target;
}
else if(target>=nums[i+1] && target<=nums[nums.length-1])
{
int lo=i+1,hi=nums.length;
while(lo<hi)
{
int mid=lo+(hi-lo)/2;
if(nums[mid]<target)
lo=mid+1;
else
hi=mid;
}
return lo<nums.length && nums[lo]==target;
}
else
return false;
}
}
理论上最坏时间复杂度也为O(n),空间复杂度O(1)。但实际运行效率中等,beat 55.25%!
思路三:直接采用二分法
class Solution {
public boolean search(int[] nums, int target) {
int len = nums.length;
if (len == 0) return false;
if (len == 1) return nums[0] == target;
int start = 0, end = len - 1;
while (start < end)
{
while (start < len - 1 && nums[start+1] == nums[start])
start++;
while (end > 0 && nums[end-1] == nums[end])
end--;
if (start >= end) break;
int mid = start + (end - start) / 2;
if (nums[mid] == target)
return true;
if (nums[mid] >= nums[start]) {
if (target >= nums[start] && target < nums[mid]) {
end = mid - 1;
} else {
start = mid + 1;//Missed!
}
//System.out.println(nums[mid]);
} else if (nums[mid] <= nums[end]) {
if (target <= nums[end] && target > nums[mid])
start = mid + 1;
else
end = mid - 1;//Missed!
}
}
return nums[start] == target;
}
}