LeetCode 👉 HOT 100 👉 搜索旋转排序数组 - 中等题

1,162 阅读2分钟

这是我参与11月更文挑战的第24天,活动详情查看:2021最后一次更文挑战

题目

整数数组 nums 按升序排列,数组中的值 互不相同 。

在传递给函数之前,nums 在预先未知的某个下标 k(0 <= k < nums.length)上进行了 旋转,使数组变为 [nums[k], nums[k+1], ..., nums[n-1], nums[0], nums[1], ..., nums[k-1]](下标 从 0 开始 计数)。例如, [0,1,2,4,5,6,7] 在下标 3 处经旋转后可能变为 [4,5,6,7,0,1,2] 。

给你 旋转后 的数组 nums 和一个整数 target ,如果 nums 中存在这个目标值 target ,则返回它的下标,否则返回 -1 。

思路

搜索一个数组中,是否存在某个数,存在则返回该数的下标,不存在返回 -1,这不就是 Array.indexOf 方法的定义么 😂😂😂

image.png

你别说,这方法效率还不错

思考: 注意到题目给的是一个旋转后的有序数组;虽然经过了旋转,但它局部依然是有序的,二分法查找有序数组,在适合不过了,具体步骤如下:

  • 初始时定义两个指针 left = 0right = n - 1

  • left < right 时遍历

    • 取中间数 mid = Math.floor((right - left) / 2) + left

    • 如果 left、mid、right 中任何一个 nums[i] === targte,返回响应的索引

    • 如果 nums[left] < nums[mid],代表前半部分有序

      • 判断 target 是否处于该有序区间内,在区间内则将 right = mid - 1,否则 left = mid + 1
    • 上一步不成立,则代表后半部分有序

      • 同理判断 target 是否处于该有序区间内,在区间内则将 left = mid + 1,否则 right = mid - 1
  • 重复上述步骤

  • 上面如果没有返回,代表找不到 targte,最后返回 -1

代码如下

    /**
     * @param {number[]} nums
     * @param {number} target
     * @return {number}
     */
    var search = function(nums, target) {
        let n = nums.length;

        if(!n) return -1;

        if(n === 1) return nums[0] === target ? 0 : -1;

        let left = 0, right = n - 1;

        while(left < right) {
            let mid = Math.floor((right - left) / 2) + left;

            if(nums[mid] === target) return mid;
            if(nums[left] === target) return left;
            if(nums[right] === target) return right;

            // 前半部分有序
            if(nums[left] < nums[mid]) {
                // 在 left - mid 区间内
                if(nums[left] < target && target < nums[mid]) {
                    right = mid - 1;
                } else {
                    left = mid + 1;
                }

            } else {
                // 后半部分有序
                if(nums[mid] < target && target < nums[right]) {
                    // 在 mid - right 区间内
                    left = mid + 1;
                } else {
                    right = mid - 1;
                }
            }

        }

        return -1;
    };

小结

二分算法查找有序数组,这是个利器,要记得用哦~

LeetCode 👉 HOT 100 👉 搜索旋转排序数组 - 中等题

合集:LeetCode 👉 HOT 100,有空就会更新,大家多多支持,点个赞👍

如果大家有好的解法,或者发现本文理解不对的地方,欢迎留言评论 😄