【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
转载请注明出处及链接 谢谢