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;
        
    }
};
``
相关推荐
B站_计算机毕业设计之家2 小时前
计算机毕业设计:Python股票投资辅助决策系统 django框架 request爬虫 协同过滤算法 数据分析 可视化 大数据 大模型(建议收藏)✅
爬虫·python·深度学习·算法·django·flask·课程设计
_日拱一卒2 小时前
LeetCode:随机链表的复制
算法·leetcode·链表
菜菜的顾清寒2 小时前
力扣笔记自用
笔记·算法·leetcode
故事还在继续吗2 小时前
C++11关键特性
开发语言·c++·算法
zzzsde2 小时前
【Linux】线程概念与控制(2)线程控制与核心概念
linux·运维·服务器·开发语言·算法
Gh0st_Lx2 小时前
【8】分类任务原理
算法·分类·数据挖掘
WolfGang0073212 小时前
代码随想录算法训练营 Day45 | 图论 part03
算法·图论
a里啊里啊2 小时前
软考-软件评测师:知识点整理(六)——数据结构与算法
数据结构·算法·链表·软考·软件评测师
想带你从多云到转晴2 小时前
06、数据结构与算法---二叉树
java·数据结构·算法