leetcode-81-Search in Rotated Sorted Array II-二分查找

leetcode-81-Search in Rotated Sorted Array II-二分查找

题目链接

https://leetcode.com/problems/search-in-rotated-sorted-array-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

Example 2:

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

Follow up:

  • This is a follow up problem to Search in Rotated Sorted Array, where nums may contain duplicates.
  • Would this affect the run-time complexity? How and why?

原本有一个有重复元素的升序列,然而把它分成两半,后面一半放到前面来了,比如:[4,5,6,7,0,1,2]。现给定一个数target,要求回答在这个数列中能否查找到target

分析

和上一版leetcode-33-Search in Rotated Sorted Array-二分查找很相似。

------------以下照抄了上一版的思路2333------------

比较直观地可以观察到,当我们把数组进行划分的时候,至少有一边是有序的——要么左边是有序的,要么右边是有序的(当然也有可能两边都是有序的)。

比如:[12,13,14,15,16,17,1,2,3,4]的左半边[12,13,14,15,16]是有序的,[17,1,2,3,4]是无序的。

那么问题可以简化一下——

假如我们找到了有序的那一半,并且target就在这半的范围里,那么直接可以在这一半里搜索target了;否则就在另一半里进行搜索。

------------以上照抄了上一版的思路2333------------

但是!!!

存在重复元素的情况下,判断有序的条件需要更严苛一点,比如:[2,5,6,2,2,2,2,2]被分割后,左半边照之前代码会被认为是有序的,因此需要做严格递增的判断

代码

public boolean search(int[] nums, int target) {
        int l = 0, r = nums.length - 1;
        boolean ans = false;
        while (l <= r) {
            int mid = (l + r) / 2;
            if (nums[mid] == target) ans = true;
            
            // 假如左边严格递增
            if (nums[l] < nums[mid]) {
            	// ...且target在左半边的范围内,则对左半边进行搜索;否则搜索右半边。下同。
                if (nums[l] <= target && target <= nums[mid]) {
                    r = mid;
                } else {
                    l = mid + 1;
                }
            } else if (nums[l] > nums[mid]) {
                if (nums[mid + 1] <= target && target <= nums[r]) {
                    l = mid + 1;
                } else {
                    r = mid;
                }
            } else {
            	// 即出现像半边为[2,5,6,2]的情况,简单起见可以选择掐头或者去尾2333,反正都是重复的,但为了下标的连续就去掉第一个了_(:3
                l++;
            }
        }
        
        return ans;
	}

吐槽

上一版主要有这样一个问题:

if (l == r && nums[l] == target) {
	ans = l;
	break;
}

这是针对只有一个元素的数组的,不过在这一版运行起来有点问题。

这一版改进了两点——

  • nums[l] < nums[mid]用来判断严格递增
  • 需要对nums[mid]进行判断

因为第一点要求左半边数组的长度大于等于2,针对输入为[0,1]这样的数据,直接被归到if-else的最后一块,假如要查0是否存在,很显然就错过了答案。

所以还是得判断下nums[mid]是否符合,哪怕不符合,也可以缩小数组范围。【非常生硬【迫真.jpg

相关题目

leetcode-33-Search in Rotated Sorted Array-二分查找

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值