leetcode 33. 搜索旋转排序数组 及 81. 搜索旋转排序数组 II

33. 搜索旋转排序数组

问题描述

假设按照升序排序的数组在预先未知的某个点上进行了旋转。
( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] )。
搜索一个给定的目标值,如果数组中存在这个目标值,则返回它的索引,否则返回 -1 。
你可以假设数组中不存在重复的元素。
你的算法时间复杂度必须是 O(log n) 级别。
示例 1:
输入: nums = [4,5,6,7,0,1,2], target = 0
输出: 4
示例 2:
输入: nums = [4,5,6,7,0,1,2], target = 3
输出: -1

问题分析

代码

class Solution {
public:
    int search(vector<int>& nums, int target) {
        int n = nums.size();
        int left = 0,right = n-1,middle;
        while(left <= right)
        {
            middle = left + (right - left)/2;
            if(nums[middle] == target)return middle;
            if(nums[middle] >= nums[left])//这说明左半部分是完全有序的
            {
                if(target >= nums[left] && target <= nums[middle])
                {
                    right = middle -1;
                }
                else{
                    left = middle +1;
                }
            }
            else{//这说明右半部分是有序的
                if(target >= nums[middle] && target <= nums[right])
                {
                    left = middle +1;
                }
                else{
                    right = middle -1;
                }
            }
        }
        return -1;
    }
};

81. 搜索旋转排序数组 II

问题描述

假设按照升序排序的数组在预先未知的某个点上进行了旋转。

( 例如,数组 [0,0,1,2,2,5,6] 可能变为 [2,5,6,0,0,1,2] )。

编写一个函数来判断给定的目标值是否存在于数组中。若存在返回 true,否则返回 false。

示例 1:

输入: nums = [2,5,6,0,0,1,2], target = 0
输出: true
示例 2:

输入: nums = [2,5,6,0,0,1,2], target = 3
输出: false
进阶:

这是 搜索旋转排序数组 的延伸题目,本题中的 nums  可能包含重复元素。
这会影响到程序的时间复杂度吗?会有怎样的影响,为什么?

问题分析

和上一个问题的代码基本一致,只不过加了个去重的操作:

 while(left < right && nums[left]==nums[left+1])left++;
 while(left < right && nums[right]==nums[right-1])right--;

代码

class Solution {
public:
    bool search(vector<int>& nums, int target) {
         int n = nums.size();
        int left = 0,right = n-1,middle;
        while(left <= right)
        {
            while(left < right && nums[left]==nums[left+1])left++;
            while(left < right && nums[right]==nums[right-1])right--;
            middle = left + (right - left)/2;
            if(nums[middle] == target)return true;
            if(nums[middle] >= nums[left])//这说明左半部分是完全有序的
            {
                if(target >= nums[left] && target <= nums[middle])
                {
                    right = middle -1;
                }
                else{
                    left = middle +1;
                }
            }
            else{//这说明右半部分是有序的
                if(target >= nums[middle] && target <= nums[right])
                {
                    left = middle +1;
                }
                else{
                    right = middle -1;
                }
            }
        }
        return false;
    }
};
posted @ 2020-02-27 09:03  曲径通霄  阅读(110)  评论(0编辑  收藏  举报