81. 搜索旋转排序数组 II

69 篇文章 1 订阅
63 篇文章 0 订阅

假设按照升序排序的数组在预先未知的某个点上进行了旋转。

( 例如,数组 [0,0,1,2,2,5,6] 可能变为 [2,5,6,0,0,1,2] )。

编写一个函数来判断给定的目标值是否存在于数组中。若存在返回 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

(1)方法:暴力法
思路:直接遍历逐个比较即可;
弊端:有很多不必要的计算,浪费时间;

class Solution {
    public boolean search(int[] nums, int target) {
        return search1(nums, target);
    }
    
    //暴力法,逐个遍历
    private boolean search1(int[] nums, int target) {
        if (nums.length == 0)
            return false;
        for (int n : nums) {
            if (n == target)
                return true;
        }
        return false;
    }
}

(2)方法:双指针法
思路:双指针,一个开头一个结尾,其实不管有序数组怎么旋转,它肯定还是由两个有序数组片段组成,头指针对应的递增片段,尾指针对应的递减片段,只需要确定当前目标值属于哪个片段,然后只遍历对应该片段即可;
1,先把特殊情况剔除掉,target完全不属于这两个片段,返回false;target刚好等于头尾指针对应的值,返回true即可;
2,target处于头指针对应的递增片段,target>nums[start],直接将start+1,只要target比nums[start]大,并且start没越界,同时还要保证此时指针仍处于该递增片段,那么start++,一直重复此操作,直到不满足条件,然后判断start指针是否越界以及是该索引的值否和target相等,相等则返回true,否则false;
3,target处于尾指针对应的递减片段,和头指针的思路一样,只是end指针向左移动而已;

注2:具体可以看代码

class Solution {
    public boolean search(int[] nums, int target) {
        return search2(nums, target);
    }
    //双指针法
    private boolean search2(int[] nums, int target) {
        if (nums.length == 0)
            return false;
        //定义双指针,起始
        int start = 0, end = nums.length - 1;
        //特殊情况,超出有序数组范围肯定是false
        if (nums[start] > target && nums[end] < target)
            return false;
        //刚好等于边界值
        if (nums[start] == target || nums[end] == target)
            return true;
        //比右边界值小时
        if (nums[end] > target) {
            end --;//右指针向左移动一位,然后判断是否还大于target
            while (end >= 0 && nums[end] > target && nums[end] <= nums[end+1])
                end--;
            //此时nums[end] <= target了
            if (end < 0 || nums[end] != target) //要么遍历完成,要么在当前有序片段中不存在
                return false;
            else
                return true;
        } else {//比左边界值大时
            start ++;//左指针右移一位继续判断是否比target小
            while (start < nums.length && nums[start] < target && nums[start] >= nums[start-1])
                start ++;
            if (start >= nums.length || nums[start] != target)
                return false;
            else
                return true;
        }        
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值