# 搜索旋转排序数组 II

<p>已知存在一个按非降序排列的整数数组 <code>nums</code> ，数组中的值不必互不相同。</p>
<p>在传递给函数之前，<code>nums</code> 在预先未知的某个下标 <code>k</code>（<code>0 <= k < nums.length</code>）上进行了 <strong>旋转
    </strong>，使数组变为 <code>[nums[k], nums[k+1], ..., nums[n-1], nums[0], nums[1], ..., nums[k-1]]</code>（下标 <strong>从 0
        开始</strong> 计数）。例如， <code>[0,1,2,4,4,4,5,6,6,7]</code> 在下标 <code>5</code> 处经旋转后可能变为
    <code>[4,5,6,6,7,0,1,2,4,4]</code> 。
</p>
<p>给你 <strong>旋转后</strong> 的数组 <code>nums</code> 和一个整数 <code>target</code> ，请你编写一个函数来判断给定的目标值是否存在于数组中。如果
    <code>nums</code> 中存在这个目标值 <code>target</code> ，则返回 <code>true</code> ，否则返回 <code>false</code> 。
</p>
<p> </p>
<p><strong>示例 1：</strong></p>
<pre><strong>输入：</strong>nums = [2,5,6,0,0,1,2], target = 0<strong><br />输出：</strong>true</pre>
<p><strong>示例 2：</strong></p>
<pre><strong>输入：</strong>nums = [2,5,6,0,0,1,2], target = 3<strong><br />输出：</strong>false</pre>
<p> </p>
<p><strong>提示：</strong></p>
<ul>
    <li><code>1 <= nums.length <= 5000</code></li>
    <li><code>-10<sup>4</sup> <= nums[i] <= 10<sup>4</sup></code></li>
    <li>题目数据保证 <code>nums</code> 在预先未知的某个下标上进行了旋转</li>
    <li><code>-10<sup>4</sup> <= target <= 10<sup>4</sup></code></li>
</ul>
<p> </p>
<p><strong>进阶：</strong></p>
<ul>
    <li>这是 <a
            href="https://leetcode-cn.com/problems/search-in-rotated-sorted-array/description/">搜索旋转排序数组</a> 的延伸题目，本题中的 <code>nums</code> 
        可能包含重复元素。</li>
    <li>这会影响到程序的时间复杂度吗？会有怎样的影响，为什么？</li>
</ul>
<p>以下错误的选项是？</p>

## aop
### before
```cpp
#include <bits/stdc++.h>
using namespace std;
```
### after
```cpp
int main()
{
    Solution sol;
    vector<int> nums = {2, 5, 6, 0, 0, 1, 2};
    int target = 0;
    int res;
    res = sol.search(nums, target);
    cout << res << endl;
    return 0;
}
```

## 答案
```cpp
class Solution
{
public:
    bool search(vector<int> &nums, int target)
    {
        if (nums.empty() || nums.size() == 0)
        {
            return false;
        }
        int start = 0;
        int end = nums.size() - 1;
        int mid;
        while (start <= end)
        {
            mid = start + (end - start) / 2;
            if (nums[mid] == target)
            {
                return true;
            }
            if (nums[start] < nums[mid])
            {

                if (nums[mid] > target && nums[start] <= target)
                {
                    end = mid - 1;
                }
                else
                {
                    start = mid + 1;
                }
            }
            else
            {

                if (nums[mid] < target && nums[end] >= target)
                {
                    start = mid + 1;
                }
                else
                {
                    end = mid - 1;
                }
            }
        }

        return false;
    }
};
```
## 选项

### A
```cpp
class Solution
{
public:
    bool search(const vector<int> &nums, int target)
    {
        int first = 0, last = nums.size();
        while (first != last)
        {
            const int mid = first + (last - first) / 2;
            if (nums[mid == target])
            {
                return true;
            }
            if (nums[first] < nums[mid])
            {
                if (nums[first] <= target && target < nums[mid])
                {
                    last = mid;
                }
                else
                {
                    first = mid + 1;
                }
            }
            else if (nums[first] > nums[mid])
            {
                if (nums[mid] < target && target <= nums[last - 1])
                {
                    first = mid + 1;
                }
                else
                {
                    last = mid;
                }
            }
            else
            {
                first++;
            }
        }
        return false;
    }
};
```

### B
```cpp
class Solution
{
public:
    bool search(vector<int> &nums, int target)
    {
        if (nums.empty())
            return false;
        int i = 0, j = nums.size() - 1, mid;
        mid = (i + j) / 2;
        if (nums[mid] == target)
            return true;
        else if (mid != i && nums[i] == nums[mid])
        {
            i = mid + 1;
            while (i <= j && nums[i] == nums[mid])
                i++;
            if (i == nums.size())
            {
                i = 0;
                j = mid - 1;
                while (i <= j && nums[j] == nums[mid])
                    j--;
            }
        }
        while (i <= j)
        {
            mid = (i + j) / 2;
            if (nums[mid] == target)
                return true;
            else if (nums[mid] >= nums[i])
            {
                if (target >= nums[i] && target < nums[mid])
                {
                    j = mid - 1;
                    while (i <= j && nums[j] == nums[mid])
                        j--;
                }
                else
                {
                    i = mid + 1;
                    while (i <= j && nums[i] == nums[mid])
                        i++;
                }
            }
            else
            {
                if (target > nums[mid] && target <= nums[j])
                {
                    i = mid + 1;
                    while (i <= j && nums[i] == nums[mid])
                        i++;
                }
                else
                {
                    j = mid - 1;
                    while (i <= j && nums[j] == nums[mid])
                        j--;
                }
            }
        }
        return false;
    }
};
```

### C
```cpp
class Solution
{
public:
    bool search(vector<int> &nums, int &target)
    {
        int n = nums.size();
        if (n == 0)
            return false;
        int left = 0, right = n - 1;
        while (left <= right)
        {
            int mid = (left + right) / 2;
            if (nums[mid] == target)
                return true;
            else if (nums[mid] < nums[right])
            {
                if (nums[mid] < target && nums[right] >= target)
                    left = mid + 1;
                else
                    right = mid - 1;
            }
            else if (nums[mid] > nums[right])
            {
                if (nums[left] <= target && nums[mid] > target)
                    right = mid - 1;
                else
                    left = mid + 1;
            }
            else
                --right;
        }
        return false;
    }
};
```
