问题描述
- 给定一个数组和目标值,元素按照从小的大的顺序排列(数组元素允许重复),数组元素有可能旋转,判断该目标值是否存在数组中。
- 例如:[0,1,2,4,5,6,7],旋转后可能为[4,5,6,7,0,1,2]。如果目标值为2,返回true。
解题思路
- 一开始打算先用二分法寻找数组的旋转点,后来发现这样因为重复元素的存在无法找到旋转点。比如:1,1,3,1,1,找到nums[middle]==nums[right],无法判断middle是在旋转点前还是旋转点后。利用下面的想法,可以让right–,后面尝试实现。
- 后来参考别人的博客,不再去找旋转点,而是直接对原数组二分查找。
- 解题方法如下:
- 如果nums[middle]大于nums[left],说明左半部分是递增区域,判断target是否存在该区域。
- 如果nums[middle]小于nums[left],说明右半部份是递增区域,判断target是否存在该区域。
- 如果nums[middle]等于nums[left],无法判断两边的区域是否是递增区域,让left++。
代码
public class Solution {
public static boolean search(int[] nums,int target){
if(nums==null || nums.length==0)
return false;
int left=0;
int right=nums.length-1;
while(left<=right){
int middle=left+(right-left)/2;
if(nums[middle]==target)
return true;
if(nums[middle]>nums[left]){
if(nums[middle]>target && nums[left]<=target){
right=middle-1;
}else{
left=middle+1;
}
}else if(nums[middle]==nums[left]){
left++;
}else{
if(nums[middle]<target && target<=nums[right]){
left=middle+1;
}else {
right=middle-1;
}
}
}
return false;
}
}