Leetcode 209,713,3 滑动窗口 C++实现

Leetcode 209. 长度最小的子数组

问题:给定一个含有 n 个正整数的数组和一个正整数 target 。找出该数组中满足其总和大于等于 target 的长度最小的子数组 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0

算法:滑动窗口,左右两个指针,从最左边开始遍历,右指针 right 右移,当子数组的和 sum 满足条件(>= target)时记录长度存入 ans ,然后左指针 left 右移寻找下一个符合条件的子数组。

代码:

class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        int n = nums.size(),left = 0,sum = 0,ans = n + 1;
        for(int right = 0;right< n;right++){
            sum += nums[right];//+右面的
            while(sum >= target){
                ans = min(ans,(right - left + 1));//满足条件,存储长度
                sum -= nums[left++];//左指针右移继续找下一个
            }
        }
        return ans <= n ? ans:0;
    }
};

Leetcode 713. 乘积小于 K 的子数组

问题:给你一个整数数组 nums 和一个整数 k ,请你返回子数组内所有元素的乘积严格小于 k 连续子数组的数目。

算法:滑动窗口,从左边开始,慢慢将右指针 right 右移,满足条件则计入总数(以满足条件时的右指针为准),若 [ l , r ] 满足条件,则 [ l + 1 , r ] , [ l + 2 , r ] ... 一直到 [ r , r ] 都符合条件,则计算出公式 right - left + 1 。

代码:

class Solution {
public:
    int numSubarrayProductLessThanK(vector<int>& nums, int k) {
        if(k <= 1)  return 0;
        int left = 0,right = 0,prod = 1,ans = 0;
        for(int right = 0;right < nums.size();right++){
            prod *= nums[right];
            while(prod >= k)    prod /= nums[left++];//不满足条件,左指针右移
            ans += right - left + 1;
        }
        return ans;
    }
};

Leetcode 3. 无重复字符的最长子串

问题:给定一个字符串 s ,请你找出其中不含有重复字符的最长子串的长度。

算法:

 hash 表做法,右指针 right 右移,出现重复元素则让左指针 left 右移,直到将重复元素消除,再更新窗口长度最大值 ans

代码:

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        int left{},ans{};
        unordered_set<char>window;// 维护从下标 left 到下标 right 的字符
        for(int right = 0;right < s.size();right++){
            char c = s[right];
            // 如果窗口内已经包含 c,那么再加入一个 c 会导致窗口内有重复元素
            // 所以要在加入 c 之前,先移出窗口内的 c
            while(window.count(c)) window.erase(s[left++]); // 缩小窗口
            window.insert(c);// 加入 c
            ans = max(ans,right - left + 1);// 更新窗口长度最大值
        }
        return ans;
    }
};
  • 18
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值