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

Leecode 704. 二分查找(要掌握 二分法是面试常考题

题目链接:704二分查找
文章讲解:二分查找
视频讲解:b站二分查找
状态: 通过

看到题目的第一想法

数组有序且无重复元素 考虑是否可以使用二分法
二分查找,先定义初始区间,然后进行区间更新,不断比较nums[mid]和target的值

看完代码随想录之后的想法

  • 注意区间:
    • 左闭右闭区间
      - 初始化: left = 0; right = nums.length - 1; while(left <= right)
      - 更新区间 :left = mid + 1; right = mid - 1;
    • 左闭右开区间
      - 初始化:left = 0; right = nums.length; while(left < right)
      - 更新区间 left = mid + 1; right = mid;

综上,二者的区别在于右区间right的初始化和更新

自己实现过程中遇到哪些困难

区间更新不太明确
mid定义在了while外面导致没有更新,代码出错

今日收获

  1. 对二分法中区间的更新过程理解更加清晰
  2. int mid = left + ((right - left) / 2);// 防止溢出 等同于(left + right)/2
// An highlighted block
// 时间复杂度:O(log n)
// 空间复杂度:O(1)
class Solution {
    public int search(int[] nums, int target) {
        int left = 0;
        int right = nums.length - 1;
        while(left <= right){
            int mid = left + ((right - left) / 2);// 防止溢出 等同于(left + right)/2
            if(nums[mid] == target){
                return mid;
            }else if(nums[mid] > target){
                right = mid - 1;
            }else{
                left = mid + 1;
            }           
        }        
        return -1;
    }
}

Leecode 35. 搜索插入位置

题目链接:35. 搜索插入位置

自己实现过程中遇到哪些困难

如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
这种情况不知道如何处理

// 704题目代码中最后一行的 return -1; 改为 return right + 1;
// 其他代码完全相同

Leecode 34. 在排序数组中查找元素的第一个和最后一个位置

题目链接:34. 在排序数组中查找元素的第一个和最后一个位置

自己实现过程中遇到哪些困难

想法:找到一个目标值后向左向右遍历是否有和目标值相等的值,结果超时。
查看题解后优化代码,用2次二分查找来实现

// 两次二分查找
class Solution {
    public int[] searchRange(int[] nums, int target) {
        int first = -1; // 初始化左右边界
        int last = -1;  // 初始化左右边界
    // 找第一个等于target的位置
        int left = 0;
        int right = nums.length - 1;
        while(left <= right){
            int mid = left + ((right - left) / 2);// 防止溢出 等同于(left + right)/2
            if(nums[mid] == target){
                first = mid;
                right = mid - 1; // 在target左边进行二分查找
            }else if(nums[mid] > target){
                right = mid - 1;
            }else{
                left = mid + 1;
            }           
        }
    // 最后一个等于target的位置
        left = 0;
        right = nums.length - 1;
        while(left <= right){
            int mid = left + ((right - left) / 2);// 防止溢出 等同于(left + right)/2
            if(nums[mid] == target){
                last = mid;
                left = mid + 1; // 在target右边进行二分查找
            }else if(nums[mid] > target){
                right = mid - 1;
            }else{
                left = mid + 1;
            }           
        }       
        return new int[]{first, last};
    }
}

Leecode 27. 移除元素(要掌握

题目链接:27 移除元素
文章讲解:移除元素
视频讲解:b站移除元素
状态: 通过
题目建议: **暴力的解法,可以锻炼一下我们的代码实现能力,建议先把暴力写法写一遍。 双指针法 是本题的精髓,今日需要掌握,至于拓展题目可以先不看。 **

自己实现过程中遇到哪些困难

用快慢指针实现,不清楚快指针和慢指针分别代表什么

看完代码随想录之后的想法

快指针:寻找新数组的元素 ,新数组就是不含有目标元素的数组
慢指针:指向更新 新数组下标的位置

今日收获

熟悉了快慢指针的应用和数组相关操作

// 快慢指针
class Solution {
    public int removeElement(int[] nums, int val) {
        int slowIndex = 0; 
        for(int fastIndex = 0; fastIndex < nums.length; fastIndex++){
            if(nums[fastIndex] != val){
                nums[slowIndex] = nums[fastIndex];
                slowIndex++;
            }
        }
        return slowIndex;

    }
}
// 暴力解法 2次for
class Solution {
    public int removeElement(int[] nums, int val) {
        int len = nums.length;
        for(int i = 0; i < len; i++){
            if(nums[i] == val){
                for(int j = i + 1; j  < len; j++){
                    nums[j - 1] = nums[j];
                }  
                i--; // 因为下标i以后的数值都向前移动了一位,所以i也向前移动一位
                len--; // 此时数组的大小-1              
            }
            
        }
        return len;

    }
}
  • 19
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值