【代码随想录】算法训练营day1 | 力扣704二分查找、27移除元素

LeetCode704二分查找

代码随想录: 二分查找
力扣: 704

初印象

1.题目条件:升序数组,所有元素不重复,存在返回下标否则返回-1。

2.二分查找法,边界条件很多,考虑使用while循环主要有两种写法,首要区别在于left等于right时是否结束循环。
首先根据循环不变量原则确定区间开闭情况,区间就是不变量!上述条件、赋值在选择左闭右闭或者左闭右开时有所不同。
3.什么是循环不变量原则?链接: 循环不变量原则

4.左闭右闭写法中,下列代码为何能防止溢出?为何能溢出

// 二分法,区间为左闭右闭时middle赋值
int middle = left + ((right - left) / 2);// 防止溢出 等同于(left + right)/2

两个很大的int数相加可能会导致溢出
( x + y ) / 2 = x + ( y − x ) / 2 (x+y)/2=x+(y-x)/2 (x+y)/2=x+(yx)/2

看视频讲解后的想法

1.int类型相加可能越界
2.二分查找法,right的初始赋值会根据区间情况不同发生变化,
左闭右开时,right=nums.size();
左闭右闭,right=nums.size()-1;
3.左闭右开时,right更新为middle,left更新为middle+1。
4.左闭右闭时,right更新为middle-1,left更新为middle+1。

实现过程中遇到的问题

// 左闭右开二分法
class Solution {
public:
    int search(vector<int>& nums, int target) {
        int left,right,middle;
        left=0;//左闭右开式
        right=nums.size();//加括号
        while(left<right){//进入循环,左闭右开,左右不相等
            middle=left+(right-left)/2;
            if(target>nums[middle]){//左边界右移,用中括号包裹
                left=middle+1;
            }else if(target<nums[middle]){//右边界左移
                right=middle;
            }else{
                return middle;
            }
        }
    //未找到目标值
    return -1;
    }
};

line7 right=nums.size()加括号
line10 nums[middle]中括号
line9 middle赋值放到循环开头
line12 else if和line14else格式
line19在search函数体内放未找到返回-1

总结

1.循环不变法,本题区间不变,确定区间开闭方式后赋值和条件才能确定。否则将是一片混乱。
2.c++数组的一些语法需要注意

LeetCode27移除元素

代码随想录: 移除元素
力扣: 27

初印象

给你一个数组 nums 和一个值 val,你需要原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度
不要使用额外的数组空间,你必须仅使用 O(1) 额外空间原地 修改输入数组
元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。

1.c++指针语法
2.原地移动数组

看讲解后的想法

1.数组元素只能覆盖
2.无需考虑删除后缩小的数组空间里存放了什么
3.暴力解法可以过,时间复杂度O(n²)
4.双指针法(快慢指针法)只需一个for循环,时间复杂度O(n)

实现过程中的问题

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        int slow=0;
        for(int quick=slow;quick<nums.size();quick++)
        {
            if(nums[quick]!=val){
                nums[slow]=nums[quick];
                slow++;//两个都动,若是目标数则slow不动,quick继续向前
            }
        }
        return slow;
    }
};

1.line7-9:用的是quick!=val,也就是说quick借助for循环移动,而slow借助循环体内的if条件移动,从而形成速度差异。
当碰见目标数时什么也不做,quick继续向后寻找非目标数。
4.line12,返回数组长度,即为right最后的位置

总结

暴力解法也要会,两个for循环。
双指针法巧妙地用了一个for循环,利用循环体内的if形成了速度差,最后的slow就是长度非常巧妙

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值