ID:33.搜索旋转排序数组

85 阅读1分钟

考点:二分查找

题目链接

思路

直接用二分查找的思路来做即可,重点是要搞明白为什么能用二分查找

参考题解区评论:将数组一分为二,其中一定有一个是有序的,另一个可能是有序,也能是部分有序。 此时有序部分用二分法查找。无序部分再一分为二,其中一个一定有序,另一个可能有序,可能无序。就这样循环。

解法一(自己的思路)

使用递归

var search = function(nums, target) {
    let cur = -1;
    const bisearch = (left, right) => {
        if(left > right) return;
        const mid = Math.floor((left + right) / 2);
        if(nums[mid] === target) cur = mid;
        else if(nums[mid] > target && mid > 0 && nums[mid - 1] > nums[mid]) return;
        else {
            bisearch(left, mid - 1);
            bisearch(mid + 1, right);
        }
    }
    bisearch(0, nums.length - 1);
    return cur;
};

只打败了55%,不够快

解法二

参考题解的思路,代码如下:

var search = function(nums, target) {
    let left = 0, right = nums.length - 1;
    let mid = 0; // 中点
    while(left <= right) {
        // 等价于Math.floor((left + right) / 2)
        mid = (left + right) >> 1;
        if(nums[mid] === target) return mid;
        // 中点的值小于右端的值,说明右侧序列有序
        // 中点的值大于右端的值,说明左侧序列有序
        if(nums[mid] < nums[right]) {
            // target在(nums[mid], nums[right]]区间中则在此区间寻找
            // 否则在前一区间寻找
            if(nums[mid] < target && nums[right] >= target) {
                left = mid + 1;
            } else {
                right = mid - 1;
            }
        } else {
            if(nums[mid] > target && nums[left] <= target) {
                right = mid - 1;
            } else {
                left = mid + 1;
            }
        }
    }
    return -1;
};

但是才44%,明明思路更好...