第一天打卡|704.二分查找、27.移除元素

LeetCode704.二分查找

题目链接:702.二分查找

        打卡第一天,学习了二分查找,第一次知道“左闭右闭”,“左闭右开”的概念,原来我之前一直写的都是左闭右闭。二分法有几个重要的点:1. 数组必须是有序的,如果对无序的数组进行查找还需要算上排序的时间复杂度;2. 在排序时,已经和val比较过的元素已经不需要了,在“左闭右闭”、“左闭右开”方式上有不同;3. 防止溢出——寻找middle时,如果数组较大且再次搜索的位置靠后,那么left+right就有可能会超过int类型的最大值,故寻找middle时最好用left+\frac{right-left}{2}

//左闭右闭
int left=0;
int right = nums.size()-1;//左闭右闭区间,每一个数字都需要比较
while(left <= right){
    int middle = left + (right - left)/2;
    if (nums[middle] > target){
        right = middle-1;
    }
    else if (nums[middle] < target){
        left=middle+1;
    }
    else{
        return middle;
    }
}
return -1;

int left=0;
int right = nums.size();//左闭右开区间,右边的永远用不到
while(left < right){
    int middle = left + (right - left)/2;
    if (nums[middle] > target){
        right = middle;
    }
    else if (nums[middle] < target){
    left=middle+1;
    }
    else{
        return middle;
    }
}
return -1;

LeetCode27.移除元素

题目链接:27.移除元素

        只能使用O(1)的额外位置,移除数组内与val相同的值。两种做法:1. 暴力移动,嵌套循环,外层循环找val相同的数,内层循环负责把原位置后面的数前移并覆盖原来的数。缺点,当与val相同的数连续排列且后面的数字多时时,每次都要移同一堆数,时间复杂度为O(n²)。

int size=nums.size();
for(int i=0;i<size;i++){
    if(nums[i]==val){
        for(int j=i;j++;j<size-1;j++){
            nums[j]=nums[j+1];
        }
    i=i-1;
    size--;
}
return size;

2. 双指针移动法:可以看作是两个指针,指针1指向原数组,指针2指向新数组(虚拟),想象成每一次把指针1指向的不同于val的数放进新数组中。但实际上新数组是从覆盖原数组得到的,从0开始,当不等于val时,指针1和指针2同时移动并且将指针1指向的数字赋值给指针2指向的位置;当等于val时,指针2不动,指针1动。

int secondInx=0;
for(int firstInx = 0; firstInx < nums.size(); firstInx++){
    if (nums[firstInx] != val){
        nums[secondInx] = nums[firstInx];
        secondInx++;
    }
}
return secondInx;

指针1只遍历数组一次,指针2没有后退,时间复杂度为O(n).

  • 8
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值