代码随想录算法训练营Day1|二分查找+移除元素

数组基础

代码随想录文章讲解[数组基础](https://www.programmercarl.com/%E6%95%B0%E7%BB%84%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.html)

主要两点:

  1. 地址空间连续性
  2. 下标从0开始

地址空间连续性导致数组元素不能删除,只能覆盖 -> 在增删元素时移动其他元素

704 二分查找

代码随想录文章讲解[二分查找] (https://www.programmercarl.com/0704.%E4%BA%8C%E5%88%86%E6%9F%A5%E6%89%BE.html#%E7%AE%97%E6%B3%95%E5%85%AC%E5%BC%80%E8%AF%BE)
Leetcode题目[二分查找](https://leetcode.cn/problems/binary-search/)

条件
  1. 数组有序
  2. 无重复元素
思路

根据中间元素与目标元素对比确定搜索区间

代码

两种写法:左闭右闭区间 和 左闭右开区间 (注意区间的边界)
主要区别就是right变量取值的问题

左闭右闭区间

class Solution {
public:
    int search(vector<int>& nums, int target) {
        int left = 0, right = sizeof(nums)/sizeof(int) - 1;
        int mid = 0;
        while(left<=right){
            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;
    }
}; 

左闭右开区间

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

移除元素

代码随想录文章讲解[移除元素](https://www.programmercarl.com/0027.%E7%A7%BB%E9%99%A4%E5%85%83%E7%B4%A0.html#%E7%AE%97%E6%B3%95%E5%85%AC%E5%BC%80%E8%AF%BE) Leetcode题目[移除元素](https://leetcode.cn/problems/remove-element/)

思路

一眼暴力解法 双循环
学习到了双指针法 包含快慢指针和双向指针
快慢指针即 快指针寻找新数组中元素(即与target不同的元素) 而慢指针寻找与target相同的元素
双向指针即 左指针寻找与target相同元素 右指针寻找与target不同的元素 在找到后交换 (条件是可以改变数组元素的顺序)

代码

暴力法

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        int len = nums.size();
        for(int i=0; i<len; i++){
            if(nums[i]==val){
                for(int j=i+1; j<len; j++){
                    nums[j-1] = nums[j];
                }
                len--; 	//注意找到后减小遍历长度
                i--; //数组元素全部向前移动->遍历索引也要向前移动
            }
        }
        return len;
    }
};

快慢指针法

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

双向指针法

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        int left = 0, right = nums.size() - 1;
        while(left<=right){
            while(left<=right && nums[left] != val){
                left++;
            }
            while(left<=right && nums[right] == val){
                right--;
            }
            nums[left] = nums[right];
            left++;
            right--;
        }    
        return left;
    }
};
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值