假设按照升序排序的数组在预先未知的某个点上进行了旋转。
( 例如,数组 [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
答案:
1public boolean search1(int[] nums, int target) {
2 int left = 0, right = nums.length - 1, mid;
3 while (left <= right) {
4 mid = (left + right) >> 1;
5 if (nums[mid] == target) return true;
6 if ((nums[left] == nums[mid]) && (nums[right] == nums[mid])) {
7 ++left;
8 --right;
9 } else if (nums[left] <= nums[mid]) {
10 if ((nums[left] <= target) && (nums[mid] > target))
11 right = mid - 1;
12 else
13 left = mid + 1;
14 } else {
15 if ((nums[mid] < target) && (nums[right] >= target))
16 left = mid + 1;
17 else
18 right = mid - 1;
19 }
20 }
21 return false;
22}
解析:
可以把数组看成两部分,每一部分都是排过序的,然后用二分法查找。再来看一种解法
1public boolean search2(int[] nums, int target) {
2 if (nums.length == 0)
3 return false;
4 int h = 0;
5 while (h != nums.length - 1 && nums[h] == nums[nums.length - 1]) h++;
6 int L = h, R = nums.length - 1, M = (L + R) / 2;
7 while (L < R) {
8 if (nums[M] == target)
9 return true;
10 else if ((nums[h] <= target) ^ (target <= nums[M]) ^ (nums[M] < nums[h]) == false)
11 R = M;
12 else
13 L = M + 1;
14 M = (L + R) / 2;
15 }
16 return (L == R && nums[L] == target) ? true : false;
17}
上面中的3个结果进行异或,只有1个为false,或者3个都为false,结果成为false。这种解法其实更绕一些。