解题报告:LeetCode Search in Rotated Sorted Array II(循环数字查找)

题目出处:https://leetcode.com/problems/search-in-rotated-sorted-array-ii/

题意描述:

给定一循环数组,查找目标值是否在该数组中。

解决思路:

由于这是Search in Rotated Sorted Array的后续题目,因此我想为了解决这道题我们有必要先解决上一道题。也就是不重复的情况下的查找。由于数组不重复,因此我们只需要先找出突变的位置即可调用经典的二分查找。而查找突变位置也可以通过二分的方式给出。附代码如下(其中find_mid函数为寻找突变点的函数,binary_search为普通的二分查找,search在调用find_mid获得突变点的位置后调用binary_search查找并获取结果)。

 1 class Solution {
 2 public:
 3     int find_mid(vector<int>& nums, int l, int r)
 4     {
 5         if(l == r)
 6             return r;
 7         int pos = (r+l)/2;
 8         if(nums[pos] >= nums[0] && nums[pos+1] < nums[0])
 9             return pos;
10         else if(nums[pos] < nums[0])
11             return find_mid(nums, l, pos-1);
12         else
13             return find_mid(nums, pos+1, r);
14     };
15 
16     int binary_search(vector<int>& nums, int target, int l, int r)
17     {
18         if(l > r)
19             return -1;
20 
21         int mid = (l+r)/2;
22         if(nums[mid] == target)
23             return mid;
24         else if(nums[mid] < target)
25             return binary_search(nums, target, mid+1, r);
26         else
27             return binary_search(nums, target, l, mid-1);
28     }
29 
30     int search(vector<int>& nums, int target) {
31         int mid = find_mid(nums, 0, nums.size()-1);
32         if(nums[0] > target)
33         {
34             if(mid < nums.size()-1)
35                 return binary_search(nums, target, mid+1, nums.size()-1);
36             else
37                 return -1;
38         }
39         else
40             return binary_search(nums, target, 0, mid);
41     };
42 };
View Code

上述代码在OJ果断AC,将这道题解决后,我们只需要将之修改为可处理重复情况即可。首先我们尝试将上述代码的稍作修改提交试试效果。修改后的代码如下:

 1 class Solution {
 2 public:
 3     int find_mid(vector<int>& nums, int l, int r)
 4     {
 5         if(l == r)
 6             return r;
 7         int pos = (r+l)/2;
 8         if(nums[pos] >= nums[0] && nums[pos+1] < nums[0])
 9             return pos;
10         else if(nums[pos] < nums[0])
11             return find_mid(nums, l, pos-1);
12         else
13             return find_mid(nums, pos+1, r);
14     };
15 
16     int binary_search(vector<int>& nums, int target, int l, int r)
17     {
18         if(l > r)
19             return -1;
20 
21         int mid = (l+r)/2;
22         if(nums[mid] == target)
23             return mid;
24         else if(nums[mid] < target)
25             return binary_search(nums, target, mid+1, r);
26         else
27             return binary_search(nums, target, l, mid-1);
28     }
29 
30     bool search(vector<int>& nums, int target) {
31         int mid = find_mid(nums, 0, nums.size()-1);
32         int pos;
33         if(nums[0] > target)
34         {
35             if(mid < nums.size()-1)
36                 pos =  binary_search(nums, target, mid+1, nums.size()-1);
37             else
38                 pos = -1;
39         }
40         else
41             pos = binary_search(nums, target, 0, mid);
42         return (pos != -1);
43     };
44 };
View Code

果然,上述代码跪了,对样例分析可知,在首位和中间的值均相等时,函数无法确定突变点在左半区间还是右半区间。于是我们需要对此特殊情况进行处理。我的做法是判定这三个值均相等时修改上界或下界,再递归调用函数求解。代码如下:

 1 class Solution {
 2 public:
 3     int find_mid(vector<int>& nums, int l, int r)
 4     {
 5         if(l == r)
 6             return r;
 7         int pos = (r+l)/2;
 8         if(nums[pos] >= nums[0] && nums[pos+1] < nums[0])
 9             return pos;
10         else if(nums[pos] < nums[0])
11             return find_mid(nums, l, pos-1);
12         else if(nums[pos] > nums[0])
13             return find_mid(nums, pos+1, r);
14         else
15         {
16             if(nums[r] == nums[pos])
17                 r --;
18             else
19                 l ++;
20             return find_mid(nums, l, r);
21         }
22     };
23 
24     int binary_search(vector<int>& nums, int target, int l, int r)
25     {
26         if(l > r)
27             return -1;
28 
29         int mid = (l+r)/2;
30         if(nums[mid] == target)
31             return mid;
32         else if(nums[mid] < target)
33             return binary_search(nums, target, mid+1, r);
34         else
35             return binary_search(nums, target, l, mid-1);
36     }
37 
38     bool search(vector<int>& nums, int target) {
39         int mid = find_mid(nums, 0, nums.size()-1);
40         int pos;
41         if(nums[0] > target)
42         {
43             if(mid < nums.size()-1)
44                 pos =  binary_search(nums, target, mid+1, nums.size()-1);
45             else
46                 pos = -1;
47         }
48         else
49             pos = binary_search(nums, target, 0, mid);
50         return (pos != -1);
51     };
52 };

上述代码获得了AC。OK,吃饭去了。

此博客中的内容均为原创或来自网络,不用做任何商业用途。欢迎与我交流学习,我的邮箱是b-liu14@mails.tsinghua.edu.cn
原文地址:https://www.cnblogs.com/bill-liu/p/5049087.html