版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_39360985/article/details/83793942
假设按照升序排序的数组在预先未知的某个点上进行了旋转。
( 例如,数组 [0,0,1,2,2,5,6]
可能变为 [2,5,6,0,0,1,2]
)。
编写一个函数来判断给定的目标值是否存在于数组中。若存在返回 true
,否则返回 false
。
示例 1:
输入: nums = [2,5,6,0,0,1,2], target = 0
输出: true
示例 2:
输入: nums = [2,5,6,0,0,1,2], target = 3
输出: false
题目分析:
这题是对搜索旋转排序数组的扩展,与它的区别是:数组中的元素可以重复,返回的结果是判断target是否在数组中,而不是返回target在数组中的位置。
因为数组中的元素可以重复,所以就会出现一个问题:可能在旋转数组时旋转的位置刚好是target,也就是说,把多个target分隔开了,比如数组 [0,0,1,2,2,5,6]
可能变为 [2,5,6,0,0,1,2]
,而target = 2,这个时候如果再用搜索旋转排序数组中的分隔方法,以target > nums[mid]
或者target < nums[mid]
为标准,就会在二分的时候出现冲突问题,所以这里应该以nums[mid] > nums[left]
或者nums[mid] < nums[left]
为标准。
这题的图形分析与搜索旋转排序数组中类似。
代码实现:
public boolean search(int[] nums, int target) { int left = 0; int right = nums.length - 1; while (left <= right) { int mid = left + (right - left) / 2; if (nums[left] == target || nums[mid] == target || nums[right] == target) return true; else if (nums[mid] > nums[left]) { if (target > nums[mid]) left = mid + 1; else { if (target > nums[left]) right = mid - 1; else left = mid + 1; } } else if (nums[mid] < nums[left]) { if (target < nums[mid]) right = mid - 1; else { if (target > nums[left]) right = mid - 1; else left = mid + 1; } } else left++;//当这二者相等的时候,无法讨论,所以只能是一次移动一个去逼近target } return false; }
主函数:
public static void main(String[] args) { S2 s = new S2(); System.out.println(s.search(new int[]{2, 5, 6, 0, 0, 1, 2}, 5)); System.out.println(s.search(new int[]{1, 1, 3, 1}, 3)); System.out.println(s.search(new int[]{1, 1, 3, 1}, 2)); }
运行结果:
true
true
false