力扣——数组(一)

一、二分法(有序数组)

1、搜索等于target的元素

法一:

直接遍历

cpp 复制代码
class Solution {
public:
    int search(vector<int>& nums, int target) {
       int i=0;
       for(i=0;i<nums.size();i++){
        if(nums[i]==target){
            return i;
        }
       }
       return -1;
    }
};

法二:

二分查找(前提:数组已经是升序排序)

1、设left、right、middle

2、让target和nums[middle]比较,分类讨论

3、移动左边界或右边界

cpp 复制代码
class Solution{
public:
int search(vector<int>& nums, int target) {
    int left=0,right=nums.size()-1; //1 设置左、右、中间变量int middle=(left+right)/2
    while(left<=right){
        int middle=(left+right)/2;
        if(target<nums[middle]){  //2 target与中间值比较并分类讨论:比中间值大还是小还是相等
            right=middle-1;  //target偏小则right左移
        }
        else if(target>nums[middle]){
            left=middle+1; //target偏大则left右移
        }
        else{
            return middle; //相等则返回当前下标middle
        }
    }
    return -1;
}
};

注意:如果是[ ],则

1、左右边界初始值:left=0,right=nums.size()-1

2、循环条件:while(left<=right) left==right时[left,right]仍有意义

3、移动边界:因为已经明确nums[middle]不等于target,所以应让left=middle+1,right=middle-1

如果是[ ),则

1、左右边界初始值:left=0,right=nums.size()

2、循环条件:while(left<right) left==right时[left,right)没有意义

3、移动边界:因为已经明确nums[middle]不等于target,所以应让left=middle+1,right=middle

2、搜索等于target的元素或target的插入位置

有序数组,可以使用二分法

cpp 复制代码
class Solution {
public:
    int searchInsert(vector<int>& nums, int target) {
      int left=0,right=nums.size()-1;
      while(left<=right){
        int middle=(left+right)/2;
        if(target==nums[middle]){
            return middle;
        }
        else if(target<nums[middle]){
            right=middle-1;
        }
        else{
            left=middle+1;
        }
      }
      return left; //找不到目标值则返回插入位置,经推算插入位置就是left
    }
};

注意:如果找不到等于target的值,则要考虑三种插入情况

插入在数组之前、数组之后、数组之中

举个最简单的例子来推算:比如[0],left=right=middle=0

target=-100时,right左移,最终right=-1,left=0,而插入位置是0

target=100时,left右移,最终left=1,right=0,而插入位置是1

综上,猜测插入位置就是left0

再看[0,4],target=3时,插入位置也是left

或者直接想,最终状态是nums[right],target,nums[left],所以把target插在left的位置

二、双指针原地操作数组

1、移除等于val的元素

法一: 双指针法

i遍历整个数组,res记录保留下来的数组,都在原地操作

cpp 复制代码
class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        int res=0;
       for(int i=0;i<nums.size();i++){
        if(nums[i]!=val){ //如果不等于val,则保留该数组元素(记录下来,在原地数组)
         nums[res++]=nums[i];
        }
       }
       return res;
    }
};

法二:有出错的先让后面的来找补

cpp 复制代码
class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
    //如果前面有等于val的值,则用后面的值来替补
    int left=0,right=nums.size()-1;
    while(left<=right){
        if(nums[left]==val){ //nums[left]等于val,则让nums[right]来替补(有出错的先让后面的来找补)
         nums[left]=nums[right--];
        }
        else{
            left++; //nums[left]不等于val,则left继续前行
        }
    }
    return left;
    }
};

2、移除重复项

cpp 复制代码
class Solution {
public:
    int removeDuplicates(vector<int>& nums) {
       int res=0;
       for(int i=0;i<nums.size();i++){
        if(i==0||nums[i]!=nums[i-1]){ //如果当前元素不等于前一个元素,说明无重复,录入
        //(注意:讨论没有前一个元素的情况)
            nums[res++]=nums[i];
        }
       }
       return res;
    }
};
相关推荐
博界IT精灵7 分钟前
栈在表达式求值中的应用(暂时看到视频3.3.2_1的25min19秒)
数据结构
weixin_3875342214 分钟前
Ownership - Rust Hardcore Head to Toe
开发语言·后端·算法·rust
xsyaaaan14 分钟前
leetcode-hot100-链表
leetcode·链表
庞轩px20 分钟前
MinorGC的完整流程与复制算法深度解析
java·jvm·算法·性能优化
Queenie_Charlie26 分钟前
Manacher算法
c++·算法·manacher
闻缺陷则喜何志丹27 分钟前
【树的直径 离散化】 P7807 魔力滋生|普及+
c++·算法·洛谷·离散化·树的直径
AI_Ming34 分钟前
Seq2Seq-大模型知识点(程序员转行AI大模型学习)
算法·ai编程
若水不如远方41 分钟前
分布式一致性(六):拥抱可用性 —— 最终一致性与 Gossip 协议
分布式·后端·算法
计算机安禾44 分钟前
【C语言程序设计】第35篇:文件的打开、关闭与读写操作
c语言·开发语言·c++·vscode·算法·visual studio code·visual studio
Wect1 小时前
React Hooks 核心原理
前端·算法·typescript