[LeetCode]Search in Rotated Sorted Array I && II

题目描述:在旋转数组中查找一个数,(II中假设有重复元素)

Suppose a sorted array 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).

You are given a target value to search. If found in the array return its index, otherwise return -1.

You may assume no duplicate exists in the array.

题目分析:先找出旋转数组的分界线(二分),继而继续二分查找该元素。

首先是I的代码

class Solution {
public:
    int search(vector<int>& nums, int target) {
        int N=nums.size();
        if(N==0) return -1;
        if(N==1) 
        {   
            if(nums[0]!=target) return -1;
            else return 0;
        }
        
        int sep; //两个有序数组的分割线    
        if(nums[0]<nums[N-1]) sep=0;
        else sep=find_min_bs(nums,N);
        
        if(sep==0) return bs(nums, 0, N-1, target);
        if(nums[N-1]<target) return bs(nums, 0, sep-1, target);
        else return bs(nums, sep, N-1, target);
    }
    
    
    
    int find_min_bs(vector<int>& nums, int N)
    {
        int l=0, r=N-1, m;
        while(l<=r)
        {
            if(r-l==1) return r;
            m=(l+r)/2;
            if(nums[l]<nums[m]) l=m;
            if(nums[r]>nums[m]) r=m;
        }
    }
    
    int bs(vector<int>& nums, int l, int r, int target)
    {
        int m;
        while(l<=r)
        {
            m=(l+r)/2;
            if(nums[m]==target) return m;
            if(nums[m]>target) r=m-1;
            if(nums[m]<target) l=m+1;
        }
        return -1;
    }

};

然后是II的代码

class Solution {
public:
    bool search(vector<int>& nums, int target) {
        int N=nums.size();
        if(N==0) return false;
    
        int min_index=find_min_bs(nums,N);//找到最小值的下标
        
        int l=0, r=N-1;
        if(target<nums[min_index]) return false;//保证 target >= nums[min_index]
        if(min_index==0) //要是数组没有旋转
            return bs(nums,0,N-1,target);
        if(target<=nums[r])  return bs(nums,min_index,r,target);
        if(target<=nums[min_index-1]) return bs(nums,0,min_index-1,target);
        return false;
    }
    
    int find_min_bs(vector<int>& nums, int N)//找到最小值的下标
    {
        int l=0, r=N-1, m;
        if( nums[r] > nums[l] ) return 0;
        while(l<=m)
        {
            m=(l+r)/2;
            if(nums[l]==nums[m] && nums[m]==nums[r]) return search_min_inorder(nums,l,r);//duplicates
            if(r-l==1) return r;
            if(nums[m]>=nums[l]) l=m;
            if(nums[r]>=nums[m]) r=m;
        }
    }
    int search_min_inorder(vector<int>& nums, int l, int r) 
    //本来应该顺序查找的,但是可能存在1,3,1,1,1这种情况,我的目标是找到3后面1的下标
    {
        int index=l;
        int max_index=l;
        for(int i=l+1; i<=r; i++)
        {
            if(nums[index]>nums[i]) index=i;
            if(nums[max_index]<nums[i]) max_index=i;
        }
        if (max_index>l) return max_index+1;
        return index;
    }
    
    
    bool bs(vector<int>& nums, int l, int r, int target)
    {
        int m;
        while(l<=r)
        {
            m=(l+r)/2;
            if(nums[m]==target) return true;
            if(nums[m]<target) l=m+1;
            else if(nums[m]>target) r=m-1;
        }
        return false;
    }
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值