leetcode 81.Search in Rotated Sorted Array II(旋转排序数组中搜素II)

Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand.

(i.e., [0,0,1,2,2,5,6] might become [2,5,6,0,0,1,2]).

You are given a target value to search. If found in the array return true, otherwise return false.

Example 1:

Input: nums = [2,5,6,0,0,1,2], target = 0
Output: true

这是33题的变体,也是rotate一个升序数组,区别是可以有重复的数字

思路:
binary search

比如[0, 1, 2, 3, 4, 5, 6] 翻转成 [3, 4, 5, 6, 0, 1, 2]
nums[left] = 3, nums[right] = 2, nums[mid] = 6,
可以看出当nums[mid] < nums[right]时,右半边是升序的,
当nums[mid] > nums[right]时,左半边是升序的。

当判断完哪半边升序之后,我们要判断target在不在这半边里面,
比如现在右半边升序,需要判断target是不是满足nums[mid] < target <= nums[right], (左边不是<=是因为如果=,直接就返回true了),如果满足,left = mid + 1, 接下来在右半边搜索;如果不满足这个条件,则需要在左半边搜索,right = mid - 1。
左半边升序的情况一样的。

因为本题允许重复元素的出现,还有一种情况,nums[mid] == num[right] (也可以和nums[left]比较)。
这种情况比如[1, 0, 1, 1, 1], 这里nums[left] = 1, nums[right] = 1, nums[mid] = 1。
如果nums[mid] 和 nums[right]比,它们相等,需要right --;
如果nums[mid] 和 nums[left]比, 它们相等, 则需要left ++。

时间复杂度O(logn), 最差O(n)

下面代码是nums[mid] 和 nums[right]比。

    public boolean search(int[] nums, int target) {
        int n = nums.length;
        int left = 0;
        int right = n - 1;
        
        while(left <= right){
            int mid = left + (right - left) / 2;
            
            if(nums[mid] == target) return true;
            if(nums[mid] < nums[right]) { //右半边升序
                if(nums[mid] < target && target <= nums[right]) left = mid + 1; //target在右半边
                else right = mid - 1;
            } else if(nums[mid] > nums[right]) { //左半边升序
                if(nums[left] <= target && target < nums[mid]) right = mid - 1; //target在左半边
                else left = mid + 1;
            } else {
                right --; //如果前面if是nums[mid]和nums[left]比,则left ++
            }
        }
        return false;
    }

虽然上面是binary search, 但其实测试的时候发现线性搜索更快。

public boolean search(int[] nums, int target) {
    int n = nums.length;
    for(int i = 0; i < n; i++) {
        if(nums[i] == target) return true;
    }
    return false;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蓝羽飞鸟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值