【Leetcode】【Search in Rotated Sorted Array】【搜索旋转排序数组】【C++】

旋转数组二分查找
本文介绍了一种在旋转排序数组中进行二分查找的算法,该算法能够在O(log n)的时间复杂度内找到目标值的索引。文章详细解释了传统二分查找的局限性,并提出了一种适用于旋转数组的改进算法。
  • 题目:

假设按照升序排序的数组在预先未知的某个点上进行了旋转。( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] )。

       搜索一个给定的目标值,如果数组中存在这个目标值,则返回它的索引,否则返回 -1 。

       你可以假设数组中不存在重复的元素。

       你的算法时间复杂度必须是 O(log n) 级别。

  • 思路:

由于时间复杂度要求,故显然不能使用遍历算法。猜想还是要“二分查找”

二分查找简述:  任务:对于给定递增序列,查找是否有目标值target,若有求其在序列中的位置; 算法:比较target与中间位置值得大小关系,若小于中间值,则原任务可转化为查找左半段序列中target的存在性;若大于中间位置值,则原任务可转化为查找右半段序列中target的存在性;通过与中间值的比较,不断砍掉一半候选序列,从而达到了O(log n)的时间复杂度;

传统二分查找代码:

  • int find(vector<int> &nums, int target)
    
    {
       int len=nums.size();
       int i=0, j=len-1;
       while(i<=j)
       {
          int mid=(i+j)/2;
          if(target==mid)
             return mid;
          else if(target<a[mid])
             j=mid-1;
          else 
             i=mid+1;
       }
       return -1;
    }

     

 

回到本题目对于某给定旋转排序数组,将其从中间分为两段,得到 [a0, a1, ...,amid  , amid+1, ... aN]  ,则显然肯定是有至少一个半段是升序排列的

假设左边半段是升序排列(即a0< a1< ...<amid)。如果target满足“大于等于a0 且小于amid”,则可以砍掉后半段;若target不满足“大于等于a0 且小于amid”,则可以砍掉前半段;

同理,若右边是升序排列,则类似处理。

  • 代码:
    class Solution {
    public:
        int search(vector<int>& a, int target) {
            int len = a.size();
            int pos = -1;
            int i = 0, j = len - 1;
            while(i<=j)
            {
                int mid = (i+j)/2;
                if(a[mid]==target)
                {
    pos
    =mid;
    break;
    }
    if(a[i]<=a[mid]) //左半段为升序序列 { if(target>=a[i] && target<a[mid]) //target肯定在左半段 { j=mid-1; } else //target肯定在右半段 { i=mid+1; } } else //右半段为升序序列 { if(target>a[mid] && target<=a[j]) //target值在右半段 { i=mid+1; } else //target值在左半段 { j=mid-1; } } } return pos; } };
  • 转载请注明出处  :https://www.cnblogs.com/dreamer123/p/9971257.html

 

转载于:https://www.cnblogs.com/dreamer123/p/9971257.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值