【路飞】算法与数据结构-搜索旋转排序数组 II

106 阅读1分钟

不管全世界所有人怎么说,我都认为自己的感受才是正确的。无论别人怎么看,我绝不打乱自己的节奏。喜欢的事自然可以坚持,不喜欢的怎么也长久不了。

LeetCode:原题地址

题目要求

已知存在一个按非降序排列的整数数组 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,4,4,5,6,6,7] 在下标 5 处经旋转后可能变为 [4,5,6,6,7,0,1,2,4,4] 。

给你 旋转后 的数组 nums 和一个整数 target ,请你编写一个函数来判断给定的目标值是否存在于数组中。如果 nums 中存在这个目标值 target ,则返回 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

思路

  • low,high取中间值,如果跟给定的元素相等,那就找到了返回true。
  • 不等的话判断哪半边数组有序,在有序的一边判断被查找的元素是否在有序数组里面(注意左右区间),缩小查询范围,更新low,high。
  • 循环退出条件 low <= high
  • 这也是#33题的思路,但是这道题可能有重复元素,即nums[low] == nums[mid],这时候需在之前将low递增后再比较(排除掉这个重复的元素,查询范围缩小1)
  • 注意:while里面嵌套while不行,会顺序往下执行。我们期待的是low++,后面不要执行,使用if~continue
/**
 * @param {number[]} nums
 * @param {number} target
 * @return {boolean}  59-5
 */ 
var search = function(nums, target) {
    var low = 0
    var high = nums.length - 1

    while(low <= high){
        console.log('顶')
        var mid = Math.floor(low + (high - low)/2)
        if(nums[mid] == target) {
            return true
        }
        console.log('前',low,'mid',mid)
        if(nums[low] == nums[mid]){
            low++
            continue
        } // 前 0;前 1;后 1
        

        // while(nums[low] == nums[mid] && nums[low + 1] == nums[low]) {
        //     low = low+1
        // }
        console.log('后',low,'mid',mid)
    

        if(nums[low] <= nums[mid]){ //左边有序
            if(target >= nums[low] && target < nums[mid]){
                high = mid -1
            }else {
                low = mid + 1
            }
        }else {
            if(target <= nums[high] && target > nums[mid]) {
                low = mid + 1
            }else {
                high = mid - 1
            }
        }
    }

    return false
};