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;
        
    }
};
``
相关推荐
z200509301 小时前
每日简单算法题——————跟着卡尔
算法
️是782 小时前
信息奥赛一本通—编程启蒙(3395:练68.3 车牌问题)
数据结构·c++·算法
Liangwei Lin2 小时前
LeetCode 118. 杨辉三角
算法·leetcode·职场和发展
计算机安禾2 小时前
【c++面向对象编程】第24篇:类型转换运算符:自定义隐式转换与explicit
java·c++·算法
鼠鼠我(‘-ωก̀ )好困2 小时前
leetGPU
算法
我星期八休息2 小时前
Linux系统编程—基础IO
linux·运维·服务器·c语言·c++·人工智能·算法
池塘的蜗牛3 小时前
A Low-Complexity Method for FFT-based OFDM Sensing
算法
故事和你913 小时前
洛谷-【图论2-1】树5
开发语言·数据结构·c++·算法·动态规划·图论
咖啡里的茶i4 小时前
视觉显著目标的自适应分割与动态网格生成算法研究
人工智能·算法·目标跟踪
paeamecium4 小时前
【PAT甲级真题】- String Subtraction (20)
数据结构·c++·算法·pat考试·pat