代码随想录算法训练营第一天 | LeetCode704.二分查找、LeetCode27.移除元素

文章介绍了在LeetCode上的两道编程题,分别是704.二分查找和27.移除元素。对于二分查找,重点在于理解左闭右开和左闭右闭两种情况下的区间处理。而对于移除元素,提出了快慢指针法和暴力解法,强调了原地修改数组的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

LeetCode704.二分查找

题目链接:704.二分查找

思路:使用二分查找下标的前提是元素有序和无重复值,因为一旦有重复元素,使用二分查找法返回的元素下标可能不是唯一的。

遇到的难点:
  1. 什么时候跳出while循环
  2. left是等于middle+1还是middle,right同理

C++代码

class Solution {
public:
    int search(vector<int>& nums, int target) {
        // 1.元素有序(升序)
        // 2.返回下标
        // 左闭右闭
        int len = nums.size();
        int left = 0, right = len -1;
        while(left <= right) {
            int middle = (left + right) / 2;
            if (nums[middle] < target) left = middle + 1;
            else if (nums[middle] > target) right = middle -1;
            else return middle;
        }
        return -1;

    }
};
class Solution {
public:
    int search(vector<int>& nums, int target) {
    	// 左闭右开
        int left = 0;
        int right = nums.size();
        while(left < right) {
            int middle = left + ((right - left) >> 1);
            if (nums[middle] < target) left = middle + 1;
            else if (nums[middle] > target) right = middle;
            else return middle;
        }
        return -1;
    }
};
本题收获
  • 对于while (letf < right)还是写while (left < right)是对区间的定义的两种结果,第一种是区间为左闭右开[letf, right),第二种是区间左闭右闭[left,right]。因此二分有两种写法
  • 针对两种写法,改变的是right的每次循环取值。当区间为左闭右开时,右值每次都取不到,所以right = middle;当区间为左闭右闭时,右值索引会被middle取到,所以right = middle - 1

LeetCode27.移除元素

题目链接:27.移除元素

思路:首先题目要求原地移除所有数值等于val 的元素,且返回移除后数组的长度。不能开辟新的数组用于存放移除元素后的数组,那只能移动所有数值等于val的元素到原数组的末端。

遇到的难点:
  1. 如何维护修改后数组的长度

C++代码
快慢指针法

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        int slowIndex = 0;
        for (int fastIndex = 0; fastIndex < nums.size(); fastIndex ++) {
            if (nums[fastIndex] != val) nums[slowIndex ++] = nums[fastIndex];
        }
        return slowIndex;
    }
};

暴力解法

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        int size = nums.size();
        for (int i = 0; i < size; i ++) {
            if (nums[i] == val){
                for (int j = i + 1; j < nums.size(); j ++) {
                    nums[j - 1] = nums[j];
                }
                i --;
                size --;
            }
      
        }
        return size;
    }
};
本题收获
  • 快慢指针的指针各有不同的性质,快指针用于寻找新数组的元素 ,新数组就是不含有目标元素的数组,慢指针用于指向更新,新数组下标的位置。
  • 巧妙的是慢指针的值刚好等于数组移除元素后的长度,我个人理解为慢指针遍历完了所有更新的下标,最后指向移除元素数组的末端+1,形成左闭右开区间。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值