假设按照升序排序的数组在预先未知的某个点上进行了旋转。

( 例如,数组 [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 = 0right = nums.length - 1mid;
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。这种解法其实更绕一些。