代码随想录算法训练营01| 704. 二分查找、27. 移除元素

 704.二分查找

704. 二分查找 - 力扣(LeetCode)

思路:简单的二分噜,通过比较target不断缩小范围直到找到mid

学习:二分使用前提:有序数组【根据是否满足题目的条件来缩小答案所在的区间,这个就是二分的本质】

tips:

  1. 注意while条件是<=,这影响了下面mid的变化需要多移动一位【不要记太多左闭右开什么的,就记这一个左闭右闭就行】

  2. int mid = left+(right-left)>>2;   —— 避免溢出,位运算更快

class Solution {
    public int search(int[] nums, int target) {
        // 加了之后内存更大了,因为这个主要是优化时间的,现在的时间已经不需要优化了
        // if (target < nums[0] || target > nums[nums.length - 1]) {
            // return -1;
        // }

        int left = 0, right = nums.length-1;

        // 注意这里是<=,因为是可以left == right,所以变的时候需要多移动一位
        while(left <= right){
            // int mid = (left + right)/2;  -- 优化:避免溢出,位运算更快
            int mid = left+(right-left) >> 2;
            if(nums[mid] > target)
               right = mid-1;
            else if(nums[mid] < target)
               left = mid + 1;
            else return mid;  
        } 
        return -1;
    }
}

27.移除元素

 27. 移除元素 - 力扣(LeetCode)

思路:遍历,如果不相等计数器++  ❌——没有考虑到要移除数组,所以要对数组进行改变

学习:原地移除数组,那就是让后面的数据覆盖前面的数据 —— 快慢指针

tips: 

  1. if条件:不相等时直接传进入,相等时进行覆盖操作-也就是不传值不要fast目前的值
  2. 优化:反向双指针慢:指针从最后移动,如果快指针==val,就把慢指针的值给快指针,同时慢指针--【为了解决同向快慢指针的最坏情况:从头全部移动一遍】
  3. 为什么返回数值是整数,但输出的答案是数组?——输入数组是以「引用」方式传递的,return的其实就是新数组的长度

  4. 也可以使用暴力解法:一个for找相同元素,另一个forjin

class Solution {
    public int removeElement(int[] nums, int val) {
    // v1.0 ❌没有考虑到要移除数组,所以要对数组进行改变
    // 首先读题,发现只用返回长度而不用返回具体数据
    // 简化一下就是找到这个数组值不为val的次数
    // 思路:遍历,如果不相等计数器++
    //    int cnt = 0;
    //    for(int num:nums){
    //        if(num!=val) cnt++;
    //    }
    //    return cnt;

    // v2.0 双指针✔
    // 原地移除数组,那就是让后面的数据覆盖前面的数据 -- 快慢指针
    int slow = 0;
    for(int fast =0 ;fast<nums.length;fast++){
        // 不相等时直接传进入,相等时进行覆盖操作-也就是不传值不要fast目前的值
        if(nums[fast]!=val){
            nums[slow] = nums[fast];
            slow++;
            }
        }
        return slow;
    
    // v3.0 双指针优化✔ 在移除较多元素时更高效    2.0最坏的情况是全部移除
    // 思路:这里的慢指针从最后移动,如果快指针==val,就把慢指针的值给快指针,同时慢指针--
    int slow =nums.length-1;
    // 注意这里的条件是fast和slow的位置,因为末尾我们已经用slow遍历了就不需要再遍历了 
    for(int fast = 0 ;fast <= slow;fast++){
        if(nums[fast]==val){
            nums[fast] = nums[slow];
            // 注意这里fast也要--,因为要判断从慢指针来的那个是不是也是val
            fast--;
            slow--;
        }
    }
    return slow + 1;
    // 为什么返回数值是整数,但输出的答案是数组?
    // 输入数组是以「引用」方式传递的,return的其实就是新数组的长度
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值