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

  • 题目:

假设按照升序排序的数组在预先未知的某个点上进行了旋转。( 例如,数组 [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

 

posted @ 2018-11-16 20:00  dreamer123  阅读(317)  评论(0编辑  收藏  举报