力扣33、力扣81——搜索旋转排序数组

力扣33、搜索旋转排序数组

力扣33、力扣81——搜索旋转排序数组_第1张图片 思路:

首先看到这个题目就有一些不懂他是要干嘛,简单来说就是在一个数组中中是否存在一个元素,存在的话返回该元素的下标,否则返回-1,那么正常来说直接遍历数组即可,

但是,肯定不会这么简单,好歹他是一道中等题目,

这个数组是一个旋转后的数组,我们要利用他的特点来降低他的时间复杂度,达到O(logn)的复杂度完成查找。

将数组一分为二,其中一定有一个是有序的,另一个可能是有序,也可能是部分有序。此时有序部分用二分法查找。无序部分再一分为二,其中一个一定有序,另一个可能有序,可能无序。就这样循环,时间复杂度为O(logn)

代码:

class Solution {
public:
    int search(vector& nums, int target) {
        int n=nums.size();//数组nums长度
        if(n==0)return -1;//数组为空 返回-1
        if(n==1) return nums[0]==target?0:-1;//数组中只有一个元素,判断该元素是否等于target,如果相等就返回0,否则返回-1
        int l=0,r=n-1;//定义左右边界,初始化为数组的两端
        while(l<=r){
            int mid=l+(r-l)/2;//二分法 mid为数组中位数
            if(nums[mid]==target) return mid;//此时mid为找到元素的下标
            if(nums[l]<=nums[mid]){//数组nums左半部分有序
                if(nums[l]<=target&&target

力扣81、搜索旋转排序数组II

力扣33、力扣81——搜索旋转排序数组_第2张图片

思路: 

本题相对于上面的题目,只是改动了题目中数组中含有重复元素

对于数组中有重复元素的情况,二分查找时可能会有 a[l]=a[mid]=a[r],此时无法判断区间 [l,mid] 和区间[mid+1,r] 哪个是有序的,这个时候我们可以在每次二分之前取消将这种情况排除,对左右边界的元素与其相邻的元素做判断,如果相等,则l++或者r--

代码:

class Solution {
public:
    int search(vector& nums, int target) {
        int n=nums.size();//数组nums长度
        if(n==0)return false;//数组为空 返回-1
        if(n==1) return nums[0]==target?true:false;//数组中只有一个元素,判断该元素是否等于target,如果相等就返回true,否则返回false
        int l=0,r=n-1;//定义左右边界,初始化为数组的两端
        while(l<=r){
            //处理重复数字
            while(l

你可能感兴趣的:(力扣刷题笔记——二分法,leetcode,算法,c++,二分法)