Leetcode 33.81.搜索旋转排序数组(search-in-rotated-sorted-array) 1、2 Tag 数组

 [33] 搜索旋转排序数组
 *
 * https://leetcode-cn.com/problems/search-in-rotated-sorted-array/description/
 *
 * algorithms
 * Medium (40.55%)
 * Likes:    1203
 * Dislikes: 0
 * Total Accepted:    226K
 * Total Submissions: 555.9K
 * Testcase Example:  '[4,5,6,7,0,1,2]\n0'
 *
 * 整数数组 nums 按升序排列,数组中的值 互不相同 。
 * 
 * 在传递给函数之前,nums 在预先未知的某个下标 k(0 )上进行了 旋转,使数组变为 [nums[k], nums[k+1], ...,
 * nums[n-1], nums[0], nums[1], ..., nums[k-1]](下标 从 0 开始 计数)。例如,
 * [0,1,2,4,5,6,7] 在下标 3 处经旋转后可能变为 [4,5,6,7,0,1,2] 。
 * 
 * 给你 旋转后 的数组 nums 和一个整数 target ,如果 nums 中存在这个目标值 target ,则返回它的索引,否则返回 -1 。
 * 
 * 
 * 
 * 示例 1* 
 * 
 * 输入:nums = [4,5,6,7,0,1,2], target = 0
 * 输出:4
 * 
 * 
 * 示例 2* 
 * 
 * 输入:nums = [4,5,6,7,0,1,2], target = 3
 * 输出:-1
 * 
 * 示例 3* 
 * 
 * 输入:nums = [1], target = 0
 * 输出:-1
 * 
 * 
 * 
 * 
 * 提示:
 * 
 * 
 * 1 
 * -10^4 
 * nums 中的每个值都 独一无二
 * nums 肯定会在某个点上旋转
 * -10^4 
 * 
 * 
 * 
 * 
 * 进阶:你可以设计一个时间复杂度为 O(log n) 的解决方案吗?
 * 
 */

思路:先遍历一编,找到旋转点,然后做两次二分查找

class Solution {
public:
    int search(vector<int>& nums, int target) {
        int k = 0;
        int n = nums.size();
        for (int i = 0; i < n-1;++i)
        {
            if(nums[i]>nums[i+1])
            {
                k=i;
                break;
            }
        }
        int res = binarysearch(nums,0,k,target);
        if(res==-1)
            res=binarysearch(nums,k+1,n-1,target);
        return res;
    }
    int binarysearch(const vector<int> &nums, int l,int r,int target)
    {
        if(l>r)
            return -1;
        if(target==nums[l])
            return l;
        else if(target==nums[r])
            return r;
        int mid=(r+l)/2;
        while(l<=r)
        {
            if(target==nums[mid])
                return mid;
            else if(target<nums[mid])
                r=mid-1;
            else if(target>nums[mid])
                l=mid+1;
            mid=(r+l)/2;
        }
        return -1;
    }
};

 II:

题目描述
Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand.

(i.e., [0,0,1,2,2,5,6] might become [2,5,6,0,0,1,2]).

You are given a target value to search. If found in the array return true, otherwise return false.

题意:一个有序数组,将数组后面一部分元素移到数组最开始的地方,在这个数组中找到某个数是否存在。33题的加强版,允许有重复元素。因为涉及到精确值的查找,我们使用二分查找模板一 。

样例
Input: nums = [2,5,6,0,0,1,2], target = 0
Output: true

思路:

先判断旋转点,然后根据target与旋转点的比较判断出位于哪一段,然后再进行二分

class Solution {
public:
    bool search(vector<int>& nums, int target) {
        int n=nums.size();
        int m=n;
        for(int i=0;i<n;++i)
        {
            if(i>0&&nums[i]<nums[i-1])
            {
                m=i;
                break;
            }
        }
        int l,r;
        if(m<n)
        {
            int l1=0,r1=max(m-1,0);
            int l2=m,r2=n-1;
            if(target>=nums[l1]&&target<=nums[r1])
            {
                l=l1;
                r=r1;
            }
            else if(target>=nums[l2]&&target<=nums[r2])
            {
                l=l2;
                r=r2;
            }
            else
                return false;
            
        }
        else
        {
            l=0;
            r=n-1;
        }
        while(l<=r)
        {
            int mid=(l+r)/2;
            if(target==nums[mid]||target==nums[l]||target==nums[r])
                return true;
            else if(target <nums[mid])
                r=mid-1;
            else
                l=mid+1;
        }
        return false;
    }
};

 

posted @ 2021-03-02 17:50  鸭子船长  阅读(60)  评论(0编辑  收藏  举报