力扣 题目33-- 搜索旋转排序数组

题目


题解


 

这题其实直接做还是比较简单的 找到旋转点 判断一下二分查找即可 但是不满足进阶的条件

进阶:你可以设计一个时间复杂度为 O(log n) 的解决方案吗?

看到O(log n) 我们就能想到二分查找 但是二分查找是有序的才能使用

由于nums是部分有序 那么我们能不能拆一下呢?即 以中间位置拆开

4,5,6,7,0,1,2->4,5,6,7  0,1,2 然后用目标值0比较一下最大和最小 发现应该是右边 然后用右边去二分查找

但是这是特殊情况 还有情况是这种

4,5,6,7,8,9,0,1,2->4,5,6,7,8  9,0,1,2这样的话显然 我们无法确定取哪个进行二分查找

但是左边已经是有序 用上面的比较方法发现 应该不是我们要找的范围 那么直接舍弃

现在看右边 继续重复上面步骤 9,0,1,2  ->9, 0  1,2 右边有序 但是判断之后不是范围 舍弃

9,0->9 0 这样就都是有序的了 放入二分搜索查找即可

一句话总结:将无序 分割变 有序 进行二分搜索

代码

 1 #include<iostream>
 2 #include<vector>
 3 using namespace std;
 4 //二分搜索
 5 int ersearch(vector<int>& nums,int target,int left,int right)
 6 {
 7     while (left <= right) {
 8         int middle = left + ((right - left) / 2);
 9         if (nums[middle] > target) {
10             right = middle - 1;    
11         }
12         else if (nums[middle] < target) {
13             left = middle + 1;    
14         }
15         else {    
16             return middle;
17         }
18     }
19     return -1;
20 }
21 //分割
22 int division(vector<int>& nums,int left, int right,int target)
23 {
24     //找到中心位置
25     int middle = left+((right - left) / 2);
26     int num = -1;
27     //如果第一个比最后一个大 那么无序 需要分割
28     if (nums[left] > nums[right]) {
29         //递归方法 以中心点进行分割 左
30         num=division(nums,left, middle, target);
31         //返回的如果不是-1 那么就是在之后的调用中找到了位置 需要返回
32         if (num != -1) {
33             return num;
34         }
35         //递归方法 以中心点进行分割 右
36         num=division(nums,middle+1,right, target);
37         //返回的如果不是-1 那么就是在之后的调用中找到了位置 需要返回
38         if (num != -1) {
39             return num;
40         }
41     }
42     //如果第一个比最后一个小 那么有序 范围判断后进行二分搜索
43     else
44     {
45         //判断target是否在这个范围内
46         if (target <= nums[right] && target >= nums[left]) {
47             return ersearch(nums, target, left, right); 
48         }
49         else
50         {
51             return -1;
52         }
53     }
54     return -1;
55 }
56 class Solution {
57 public:
58     int search(vector<int>& nums, int target) {
59         //调用分割函数
60         int position=division(nums,0, nums.size()-1, target);
61         cout << position << endl;
62         return position;
63     }
64 };
65 int main() {
66     vector<int>nums = { 5,4};
67     int target = 4;
68     Solution sol;
69     sol.search(nums, target);
70 }
View Code

 

posted @ 2022-04-23 13:33  无聊的阿库娅  阅读(9)  评论(0编辑  收藏  举报