LeetCode 81. Search in Rotated Sorted Array II(旋转有序数组,朝找目标值Ⅱ)

本文介绍了一种改进的二分搜索算法,用于在一个旋转有序且可能包含重复元素的数组中查找特定的目标值。通过结合深度优先搜索(DFS)与二分搜索,解决了因数组旋转和重复元素带来的挑战。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述:

    Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand.
    (i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2).
    Write a function to determine if a given target is in the array.
    The array may contain duplicates.

分析:
    题意:给定一个旋转有序有重复数组,一个目标值,查找该值。如果找到,返回true,否则返回false。
    思路:这道题是LeetCode 33的进化版本,仍然采用二分法假设数组nums的大小为n,目标值为target,那么两者区别在于:Ⅰ. LeetCode 30给定的是旋转有序非重复数组,已经证明,对于经过旋转的数组,任意选择一个j作为分割点,nums[0→j - 1]、nums[jn - 1]至少有一段是升序的;Ⅱ. 本题给定的是旋转有序有重复数组,则不满足这个性质,给出反例:数组 1, 3, 1, 1, 1 中查找目标值3,此时经过第一次分隔,不存在升序子数组。
    由上例可知,本题中,某些情形需要对两个子数组同时搜索,因此我们采用DFS搜索和二分法结合的方式,初始化指针left = 0,right = n - 1,则mid = left + ((right - left) >> 1)。① 如果target等于nums[left]、nums[mid]或者nums[right],那么已经找到target,返回true;② 如果target处于nums[left]和nums[mid]之间,那么继续进入左子数组[left→mid - 1]搜索;③ 如果target处于nums[mid]和nums[right]之间,那么继续进入右子数组[mid + 1→right]搜索④ 其它情况,需要同时进入两个子数组[leftmid - 1]和[mid + 1right]搜索。

代码:

#include <bits/stdc++.h>

using namespace std;

class Solution {
private:
    bool ans;
    
    void DFS(vector<int>& nums, int left, int right, int& target){
        if(ans || (left > right)){
            return;
        }
        if(left == right){
            if(nums[left] == target){
                ans = true;
            }
            return;
        }
        int mid = left + ((right - left) >> 1);
        if(nums[left] == target || nums[mid] == target || nums[right] == target) {
            ans = true;
            return;
        }
        if(nums[left] <= target && target <= nums[mid]){
            DFS(nums, left, mid - 1, target);
        }
        else if(nums[mid] <= target && target <= nums[right]){
            DFS(nums, mid + 1, right, target);
        }
        else{
            DFS(nums, left, mid - 1, target);
            DFS(nums, mid + 1, right, target);
        }
    }
    
public:
    bool search(vector<int>& nums, int target) {
        int n = nums.size();
        if(!n){
            return false;
        }
        ans = false;
        DFS(nums, 0, n - 1, target);
        return ans;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值