leetcode刷题_day8

34. Find First and Last Position of Element in Sorted Array(Medium)

  1. 时间复杂度为O(log n)肯定是要用二分查找的
    找上界和下界和找确定数不一样,是一直找,找到没有为止。
  2. 先来说思路,对于找下界,nums[mid]>=target,这样如果可以找到,则r-l=1的情况时,一定是nums[r]=target ,nums[mid] = nums[l] <target,最后一次循环l = mid+1
    然后跳出r<l的循环。
  3. 对于找上界,运行过程中发现,使用左闭右开写法,也即while(l<r),如果初始化r = nums.size()-1,则如果只有1个元素时,会不进入循环。所以换成 r =nums。size()。至于为什么最后一个数不容易跳出索引,是因为使用左闭右开写法取上确界的时候,经过实验,最后的结果要减一才是正确答案。所以即使l=nums.size(),也会减1,不会跳出索引。
    4.以后习惯用左闭右开写法,也即:
while(l<r)
        {
            mid = l + (r - l)/2;
            if(nums[mid]>=target) //大于等于看情况取
                r = mid ;
            else
                l = mid + 1;
        }
        return l;

class Solution {
public:
    vector<int> searchRange(vector<int>& nums, int target) {
        if(nums.empty()) return vector<int> {-1,-1};
        int lower = lower_bound(nums, target);
        int upper = upper_bound(nums, target);
        if(nums[lower]!= target )
            return vector<int> {-1,-1};
        else
            return vector<int> {lower,upper};  
    }
    int lower_bound(vector<int> & nums, int target)
    {
        int l = 0,r = nums.size()-1,mid;
        while(l<r)
        {
            mid = l + (r - l)/2;
            if(nums[mid]>=target)
                r = mid ;
            else
                l = mid + 1;
        }
        return l;
    }
    int upper_bound(vector<int> & nums, int target)
    {
        int l = 0,r = nums.size(),mid;
        while(l<r)
        {
            mid = l + (r-l)/2;
            if(nums[mid]>target)
                r = mid ;
            else
                l = mid + 1;
        }
        return l -1;
    }
};

81. Search in Rotated Sorted Array II (Medium)

  1. 使用二分查找,对于当前的中点,如果它指向的值小于等于右端,则右区间是排好序的,反之左区间是排好序的。如果遇到左端点等于右端点等于中间点,这时无法判断哪边是排好序的。所以只能左端点自加一这种方法换端点尝试,或者左端点自加一,右端点自减一。
class Solution {
public:
    bool search(vector<int>& nums, int target) {
        int l = 0,r = nums.size()-1,mid;
        while(l<=r)
        {
            mid = l + (r-l)/2;
            if(nums[mid]==target)
                return true;
            if(nums[mid]==nums[l] && nums[mid] == nums[r])
                ++l;
            else if(nums[mid]<=nums[r]){
                if(target>nums[mid] && target<=nums[r])
                    l = mid + 1;
                else
                    r = mid - 1;
            }
            else{
                if(target>=nums[l] && target<nums[mid])
                    r = mid - 1;
                else
                    l = mid + 1;
            }   
        }
        return false;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值