Leetcode刷题总结(1)

1.双指针

1.1滑动窗口

1.11定长型滑动窗口

题目特征:存在一个固定长度(k)的子串,寻找其中的符合条件的元素个数

解题步骤:

​ 先定义右边界,对右边界的元素开始遍历,当有边界的元素满足条件时进入统计,此时再定义右边界left=right-k+1;(因为窗口长度为k,也就是right-left+1=k,就可以反解出left),当left<0时(此时窗口还未形成)所以continue;令右端点继续向后移动。当left==0时进行答案的更新(此步骤需按题目而定)。当left>0时,开始让左端点元素出窗口,此时对右端点元素进行判断,如果满足条件就需要对统计数据进行更改。

时间复杂度O(n)只进行了一次遍历

1.12不定长滑窗

此类题目大体上特征为:求最长/短子数组or子数组个数

此类题目大概率涉及了hash表部分的内容

(1)最长/短子串型

以该题为例,该题表面上是删除0后的最长非零子数组, 但该题可以简化思路,因为数组中只含有0/1两种数字,所以题目目标可以改成寻找只含有一个零的最长串(但是因为需要删除一个元素,统计长度的时候应该减去1)

做题步骤:因为窗口不定长,所以left不与right绑定,两个便单独定义就行,依旧先遍历右窗口元素,并统计边界条件元素,当边界元素不满足题目条件时,开始缩小窗口将left向右进行移动,并对边界元素的个数进行更新,当while维护结束后,此时就是满足条件的窗口,就可以开始更新答案

`

c++ 复制代码
class Solution {
public:
    int longestSubarray(vector<int>& nums) {
        //转换题意得求只含1个零的最长子数组
        int cnt0=0;
        int ans=0;
        for(int right=0,left=0;right<nums.size();right++){
            cnt0+=1-nums[right];
            while(cnt0>1){
                cnt0-=1-nums[left];//对统计数据开始更新
                left++;
            }
            ans=max(ans,right-left);//因为必须减去一个元素所以该题长度应该少一
        }
        return ans;
    }
};
(2)越长越满足类型(窗口越长时,满足题目条件的子串越多)

​ 该类题型在更新答案时,一般会ans+=left, 因为此类题型我们应该更加趋于关注left-1时能否满足条件从而确定left的值,当left被确定时left-1,right,left-2,right,left-3,right...0,right的子串都满足条件,数量就是left-1-0+1个也就是left个

做题步骤:

​ 依旧遍历右端点,对满足条件的数据进行统计,当统计数据达到题目要求时就可以开始缩小窗口寻找不满足条件的left**(while条件是满足题目要求的条件,因为找的是不满足时恰好位置)**,并同时对统计数据进行更新,当while完成维护时此时就找到了恰好不满足条件的左端点位置,根据 上面的推导可以得知此时满足条件的子串个数为left

c++在这里插入代码片 复制代码
class Solution {
public:
    long long countSubarrays(vector<int>& nums, int k) {
        int max_num=range::max(nums.begin(),nums.end());
        int cnt=0;
        long long ans=0;
        for(int right=0,left=0;right<nums.size();right++){
            if(nums[right]==max_num){
                cnt++;
            }
            while(cnt>=k){
                if(nums[left]==max_num){
                    cnt--;   
                }
                left++;
            } 
            ans+=left;
        }
        return ans;
    }
};
(3)越短越满足(窗口越长短,满足题目条件的子串越多)

​ 此类题目在更新答案时大概率需要**ans+=right-left+1;**因为在while循环时结束时此时的left,right是符合要求的区间,其内部的子串left+1,right.left+2,right...right,right都是满足条件的,所以总数也就是区间长度

做题步骤:

​ 依旧依旧遍历右端点,对满足条件的数据进行统计,当统计数据不满足条件时,开始缩小条件,当while**(条件为不满足题目的条件,因为该种题型需要的是缩小至刚好全部满足条件的子串的最大集合)**结束维护时,就可以更新答案了

c++ 复制代码
class Solution {
public:
    long long countSubarrays(vector<int>& nums, long long k) {
        long long ans=0,sum=0;
        for(int right=0,left=0;right<nums.size();right++){
            sum+=nums[right];
            while(sum*(right-left+1)>=k){
                sum-=nums[left];
                left++;
            }
            ans+=right-left+1;
        }
        return ans;
        
    }
};
``
相关推荐
Zik----4 分钟前
保研面试拷打
面试·职场和发展
嵌入式老牛37 分钟前
液晶段码(米/日字格)识别—倾斜校正
opencv·算法·仿射变换
luj_176839 分钟前
残熵算法:风险缓冲与效率优化的融合
c语言·开发语言·网络·经验分享·算法
oddsand11 小时前
pgvector 三大相似度算法
人工智能·算法·机器学习
运筹vivo@1 小时前
LeetCode 2574. 左右元素和的差值
算法·leetcode·职场和发展·每日一题
ychqsq2 小时前
45.新芽
经验分享·职场和发展
计算机安禾2 小时前
【数据库系统原理】第4篇:关系数据结构的形式化定义:域、笛卡尔积与关系模式
数据结构·数据库·算法
手写码匠2 小时前
手写 DeepSeek 推理引擎优化:从 FP16 到 INT4 的量化加速实战
人工智能·深度学习·算法·aigc
GuWenyue2 小时前
LeetCode 76 最小覆盖子串|JS 滑动窗口标准解法
前端·算法·面试
一只齐刘海的猫2 小时前
【Leetcode】移动零
算法·leetcode·职场和发展