不定长滑动窗口-基础篇(2)

1.题目删除子数组的最大得分

给你一个正整数数组 nums ,请你从中删除一个含有 若干不同元素 的子数组**。** 删除子数组的 得分 就是子数组各元素之

返回 只删除一个 子数组可获得的 最大得分

如果数组 b 是数组 a 的一个连续子序列,即如果它等于 a[l],a[l+1],...,a[r] ,那么它就是 a 的一个子数组。

复制代码
输入:nums = [4,2,4,5,6]
输出:17
解释:最优子数组是 [2,4,5,6]

这道题翻译成人话就是:找没有重复元素的子数组,统计最大和,子数组包含隐藏条件------连续,不是子序列。

cpp 复制代码
class Solution {
public:
    int maximumUniqueSubarray(vector<int>& nums) {
        unordered_set<int> st;
        int ans=0;
        int sum=0;
        int left=0;
        for(int x : nums){
            while(st.contains(x)){
                st.erase(nums[left]);
                sum-=nums[left];
                left++;
            }
            st.insert(x);
            sum+=x;
            ans=max(ans,sum);
        }
        return ans;
    }
};

这道题是跟力扣的第三题.无重复字符的最长子串是一样的,额外维护窗口中的元素和即可。

2.题目最多 K 个重复元素的最长子数组

给你一个整数数组 nums 和一个整数 k

一个元素 x 在数组中的 频率 指的是它在数组中的出现次数。

如果一个数组中所有元素的频率都 小于等于 k ,那么我们称这个数组是 数组。

请你返回 nums最长好 子数组的长度。

子数组 指的是一个数组中一段连续非空的元素序列。

复制代码
输入:nums = [1,2,3,1,2,3,1,2], k = 2
输出:6
解释:最长好子数组是 [1,2,3,1,2,3] ,值 1 ,2 和 3 在子数组中的频率都没有超过 k = 2 。[2,3,1,2,3,1] 和 [3,1,2,3,1,2] 也是好子数组。
最长好子数组的长度为 6 。
cpp 复制代码
class Solution {
public:
    int maxSubarrayLength(vector<int>& nums, int k) {
        int ans=0;
        int left=0;
        unordered_map<int,int> cnt;
        for(int right=0;right<nums.size();right++){
            cnt[nums[right]]++;
            while(cnt[nums[right]]>k){
                cnt[nums[left]]--;
                left++;
            }
            ans=max(ans,right-left+1);
        }
        return ans;
    }
};

对于本题,新加入元素 x=nums[right] 后,如果 x 的出现次数超过 k,则不断右移左指针 left,直到窗口内的 x 的出现次数等于 k 为止,然后用窗口大小 right−left+1 更新答案的最大值。

3.题目考试的最大困扰度

一位老师正在出一场由 n 道判断题构成的考试,每道题的答案为 true (用 'T' 表示)或者 false (用 'F' 表示)。老师想增加学生对自己做出答案的不确定性,方法是 最大化连续相同 结果的题数。(也就是连续出现 true 或者连续出现 false)。

给你一个字符串 answerKey ,其中 answerKey[i] 是第 i 个问题的正确结果。除此以外,还给你一个整数 k ,表示你能进行以下操作的最多次数:

  • 每次操作中,将问题的正确答案改为 'T' 或者 'F' (也就是将 answerKey[i] 改为 'T' 或者 'F' )。

请你返回在不超过 k 次操作的情况下,最大 连续 'T' 或者 'F' 的数目。

复制代码
输入:answerKey = "TTFF", k = 2
输出:4
解释:我们可以将两个 'F' 都变为 'T' ,得到 answerKey = "TTTT" 。
总共有四个连续的 'T' 。
cpp 复制代码
class Solution {
public:
    int maxConsecutiveAnswers(string answerKey, int k) {
        int t=0;
        int f=0;
        int left=0;
        int ans=0;
        for(int right=0;right<answerKey.size();right++){
            if(answerKey[right]=='T') t++;
            else f++;
            while(min(t,f)>k){
                if(answerKey[left]=='T') t--;
                else f--;
                left++;
            }
            ans=max(ans,right-left+1);
        }
        return ans;
    }
};

这道题目的意思就是:求 answerKey 的一个最长子串,包含至多 k 个 T 或者至多 k 个 F。

由于子串越长,越无法满足要求,有单调性,可以用滑动窗口解决。

1.遍历 answerKey,枚举子串右端点 right,同时维护最小左端点 left 以及子串中的字符个数 cnt。

2.把 answerKey[right] 的出现次数加一。

3.如果 T 和 F 的出现次数都超过 k,那么必须不断移动左端点 left,同时减少 answerKey[left] 的出现次数,直到 T 和 F 的出现次数至少有一个 ≤k。

4.循环结束后,说明子串右端点在 right 时,对应的最小左端点为 left,用子串长度 right−left+1 更新答案的最大值。

5.遍历 answerKey 结束后,返回答案。

我这个题解写的稍微清楚一点,其实也可以使用位运算来写,这样可以更快一点。

4.题目最大连续1的个数 III

给定一个二进制数组 nums 和一个整数 k,假设最多可以翻转 k0 ,则返回执行操作后 数组中连续 1 的最大个数

复制代码
输入:nums = [1,1,1,0,0,0,1,1,1,1,0], K = 2
输出:6
解释:[1,1,1,0,0,1,1,1,1,1,1]
粗体数字从 0 翻转到 1,最长的子数组长度为 6。
cpp 复制代码
class Solution {
public:
    int longestOnes(vector<int>& nums, int k) {
        int ans=0;
        int left=0;
        int cnt=0;
        for(int right=0;right<nums.size();right++){
            if(nums[right]==0) cnt++;
            while(cnt>k){
                if(nums[left]==0) cnt--;
                left++;
            }
            ans=max(ans,right-left+1);
        }
        return ans;
    }
};

cnt0 += 1 - nums[right]和cnt0 -= 1 - nums[left]

就相当于

if (nums[right] == 0) cnt0++;

if (nums[left] == 0) cnt0--;

这里是我之前写的代码,但是不方便理解,题解这样写就可以更好理解一些。

统计窗口内 0 的个数 cnt0​,则问题转化成在 cnt0​≤k 的前提下,窗口大小的最大值。

相关推荐
我在人间贩卖青春1 小时前
C++之数据类型的扩展
c++·字符串·数据类型
wangjialelele1 小时前
平衡二叉搜索树:AVL树和红黑树
java·c语言·开发语言·数据结构·c++·算法·深度优先
苏宸啊1 小时前
C++栈和队列
c++
xuxie991 小时前
day 21 双向链表以及循环链表
数据结构·链表
森G1 小时前
七、04ledc-sdk--------makefile有变化
linux·c语言·arm开发·c++·ubuntu
驱动探索者1 小时前
linux mailbox 学习
linux·学习·算法
ringking1232 小时前
autoware-1:安装环境cuda/cudnn/tensorRT库函数的判断
人工智能·算法·机器学习
大闲在人2 小时前
8. 供应链与制造过程术语:产能
算法·制造·供应链管理·智能制造·工业工程
橘颂TA2 小时前
【测试】高效浏览器操作:基础功能与优化设置大全
c++·功能测试·职场和发展·测试·web测试
一只小小的芙厨2 小时前
寒假集训笔记·以点为对象的树形DP
c++·算法