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;
        
    }
};
``
相关推荐
Dream it possible!7 小时前
LeetCode 面试经典 150_多维动态规划_交错字符串(97_C++_中等)
算法·leetcode·面试·动态规划
心抵鹊8 小时前
算法之双指针系列(一)
算法·leetcode
十二8 小时前
【洛谷题解】P1083 [NOIP 2012 提高组] 借教室(二分答案 + 差分)
数据结构·c++·算法·蓝桥杯
小此方9 小时前
[算法实战论:动态规划]回文串问题的dp解法,回文串问题的母题,以及以此为基础的派生题
算法·动态规划
Pniubi9 小时前
力扣560.和为k的子数组
算法·leetcode·职场和发展
D e re k ZH10 小时前
C++ 从零入门(一):基础语法与程序结构
数据结构·c++·算法
Pniubi10 小时前
力扣438.找到字符串中所有字母异位词
算法·leetcode·职场和发展
東隅已逝,桑榆非晚13 小时前
算法6. 双指针法-查找总价格为目标的两个商品
c++·学习·算法
Eyfcom13 小时前
〖物联网终端实战 01〗UWB 室内高精度定位:仓储 AGV 与人员的厘米级轨迹追踪
物联网·算法·物流系统·快递系统·跨境物流快递系统·物联网终端实战
bro_Java66614 小时前
《排序的底层逻辑:比较、交换与分治》
java·算法·排序算法