力扣_01_数组边界怎样快速确定

注意:前提是数组!!!数组是有序的 设容器为vector<int> nums; 查找的数字是 target

  middle = left+(right-left)>>1

一、二分查找的边界问题

主要是因为对区间的定义没有想清楚,区间的定义就是不变量。要在二分查找的过程中,保持不变量,就是在while寻找中每一次边界的处理都要坚持根据区间的定义来操作,这就是环不变量规则。

(1)右边界:

①初始:right=nums.size();循环条件:while(left<right) ;右边界确定时机:if(nums[middle]>target) right=middle

解释如下: 因为left最大值是nums.size()-1,right最大值nums.size() ,所以while循环条件left<right中没有等号;right = middle(之所以等于middle而不等于middle-1,是因为右边界确定时机:if(nums[middle]>target)已经取过middle(通过nums[middle]),但在下一次循环不能再取middle(通过nums[middle]),要不然 就是重复操作,在下一次循环的时候(left<right)注意是"<" 号 。left最大只会取到middle-1 而取不到middle)

②初始:right=nums.size()-1;循环条件:while(left<=right) ;右边界确定时机:if(nums[middle]>target) right=middle-1

解释如下: 因为left最大值是nums.size()-1,right最大值nums.size()-1 ,所以while循环条件left<=right中等号是成立的;right = middle-1(之所以是middle-1是因为这个middle在下一次循环的时候(left<=right)已经取过middle(通过nums[middle]),但在下一次循环不能再取middle而while条件是取到等号的。

(2)左边界:

if(nums[middle]<target)  left++;

原因是已经取过nums[middle]不能重复取了,只能从nums[middle+1]开始比较。

二、力扣第35题

给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。

如果数组中不存在目标值 target,返回 [-1, -1]

进阶:实现时间复杂度为 O(log n)

示例 1:

  • 输入: [1,3,5,6], 5
  • 输出: 2

解析:题设已知:vector<int>& nums; l=0;r = nums.size();

做法:①判断是否有为空的情况,如果有返回(-1,-1)

②利用二分法先确定左边界的值

③判断左边界的索引值是否与目标值target相等,不等返回(-1,-1)

④利用二分法查找结束位置的值

步骤:

vector<int> res(2,-1); //设置(-1,-1)

①判断是否有为空的情况,如果有返回(-1,-1)

if(nums.empty()) return res;

②利用二分法确定左边界的值

while(l<r){ //注意这里的r=nums.size()-1 因为这个减一是排除nums中只含有一个元素的情况
    int m=l+(r-l)/2;
    if(nums[m]>=target) r=m;
    else l=m+1;
}
if(nums[l]!=target) return res;//③判断值是否符合条件
res[0]=r; //②确定了左边界的值

④利用二分法查找结束位置的值

//首先确定右边界的值的范围是nums.size()
r=nums.size();
while(l<r){
    int m=l+(r-l)/2;
    if(nums[m]>target) r=m;
    else l=m+1;
}
res[1]=l-1;
return res;

三、对于处理数据中的元素要用双指针法

通过一个快指针和慢指针在一个for循环下完成两个for循环的工作。

int slowIndex = 0,fastIndex = 0;
for(fastIndex=0;fastIndex<nums.size();){
    if(nums[slowIndex]!=nums[fastIndex]) num[slowIndex++]=nums[fastIndex];
    fastIndex++;
}

力扣977

给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。

输入:nums = [-4,-1,0,3,10]
输出:[0,1,9,16,100]
class Solution {
public:
    vector<int> sortedSquares(vector<int>& nums) {
        for(int i=0;i<nums.size();i++) nums[i]=nums[i]*nums[i];
        vector<int> newNu(nums.size(),-1);
        int l=0,k=nums.size()-1,r=nums.size()-1;
        for(l=0;l<=r;){  //之所以有=号 是因为当两个指针指向同一个数据的时候也可以赋值
                            //如果没有 会导致最终结果首元素缺失
            if(nums[l]<=nums[r]) newNu[k--]=nums[r--];
            else newNu[k--]=nums[l++];
        }
        return newNu;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值