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

LeetCode 704. 二分查找

题目链接:704.二分查找

难度:简单

class Solution {
public:
    int search(vector<int>& nums, int target) {
        int left = 0, right = nums.size();		// 差异点1
        int mid = left + (right - left) / 2;
        while(left < right) {					// 差异点2
            mid = left + (right - left) / 2;
            if(nums[mid] == target) {
                return mid;
            } else if(nums[mid] < target) {
                left = mid + 1;
            } else {
                right = mid;					// 差异点3
            }
        }
        return -1;
    }
};
class Solution {
public:
    int search(vector<int>& nums, int target) {
        int left = 0, right = nums.size() - 1;		// 差异点1 		
        int mid = left + (right - left) / 2;		
        while(left <= right) {						// 差异点2
            mid = left + (right - left) / 2;
            if(nums[mid] == target) {
                return mid;
            } else if(nums[mid] < target) {
                left = mid + 1;
            } else {
                right = mid - 1;					// 差异点3
            }
        }
        return -1;
    }
};

关键点理解

理解二分查找两种写法的差异性的关键在于:

  1. 判断mid下标的元素是否在下一个待搜索区间内
  2. 循环什么时候终止,即判断区间内什么时候没有可供判断的元素

1. 判断mid下标的元素是否在下一个搜索区间内

已知如果nums[mid] != target,那么mid不应该出现在下一个搜索区间中

左闭右开的区间中,即[left, right)区间中,left位置在区间内,right不在,所以如果是left位置需要修改,那么应该是left=mid+1(如果left=mid,就会导致mid下标对应的数出现在下一个搜索区间内;如果是right位置需要修改,那么就可以是right=mid;

左闭右闭的区间中,即[left, right]区间中,left位置在区间内,right也在,那么此时如果right位置需要修改,就必须变为right = mid - 1,以保证nums[mid]不会出现在下一个搜索区间中

2. 循环什么时候终止,即判断区间内什么时候没有可供判断的元素

难点是什么时候可以等于,什么时候不能等于(其他简单,不讨论了)

左闭右开的区间中,即[left, right)区间中,如果left==right,此时nums[left](nums[right])不在区间中,所以此时区间中没有元素,循环不应该继续,所以循环进行的条件是while(left > right)

左闭右闭的区间中,即[left, right]区间中,如果left==right,此时nums[left](nums[right])在区间中,此时区间中还有需要判断的元素,循环应该继续,所以循环进行的条件是while(left >= right)

LeetCode 27.移除元素

题目链接 27.移除元素

难度:简单

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

关键点理解

关键点在于理解快指针和慢指针分别是做什么的

简洁地说,快指针负责搜索,慢指针负责记录。快指针搜索整个数组,不符合的元素就跳过,而每确定一个符合要求的元素,就告诉慢指针,慢指针将其记录下来,同时慢指针移向下一个记录点位。

如果感觉难以理解,可以想象出两个数组,慢指针在另一个数组上移动,而快指针将符合要求的元素拷贝过去,每拷贝一个元素,慢指针就向前移一格,所以慢指针同时也指示了数组中元素的个数

因为快指针永远不会落在慢指针后面,所以不用担心元素被覆盖,可以将两个数组合并,在同一数组上操作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值
>