leetcode力扣 2024. 考试的最大困扰度
一位老师正在出一场由 n 道判断题构成的考试,每道题的答案为 true (用 'T' 表示)或者 false (用 'F' 表示)。老师想增加学生对自己做出答案的不确定性,方法是最大化有连续相同结果的题数。(也就是连续出现 true 或者连续出现 false)。
给你一个字符串 answerKey,其中 answerKey[i] 是第 i 个问题的正确结果。除此以外,还给你一个整数 k,表示你能进行以下操作的最多次数:
每次操作中,将问题的正确答案改为 'T' 或者 'F'(也就是将 answerKey[i] 改为 'T' 或者 'F')。请你返回在不超过 k 次操作的情况下,最大连续 'T' 或者 'F' 的数目。
示例 1:
输入:answerKey = "TTFF", k = 2
输出:4
解释:我们可以将两个 'F' 都变为 'T',得到 answerKey = "TTTT"。
总共有四个连续的 'T'。
示例 2:
输入:answerKey = "TFFT", k = 1
输出:3
解释:我们可以将最前面的 'T' 换成 'F',得到 answerKey = "FFFT"。
或者,我们可以将第二个 'T' 换成 'F',得到 answerKey = "TFFF"。
两种情况下,都有三个连续的 'F'。
示例 3:
输入:answerKey = "TTFTTFTT", k = 1
输出:5
解释:我们可以将第一个 'F' 换成 'T',得到 answerKey = "TTTTTFTT"。
或者我们可以将第二个 'F' 换成 'T',得到 answerKey = "TTFTTTTT"。
两种情况下,都有五个连续的 'T'。
提示:
n == answerKey.length
1 <= n <= 5 * 10^4
answerKey[i] 要么是 'T',要么是 'F'
1 <= k <= n
题解:
字符长度最大值分为两种情况:
- 把 'T' 改成 'F'的
- 把 ’F‘ 改成 'T'的
两种情况取 max
这题可以用滑动窗口来维护一个窗口, 使窗口中要改变的字符数 sum 不超过 k 个, 同时使窗口中的元素尽可能多
滑动窗口, 不多解释了
ac代码👇, 代码请从第二个函数maxConsecutiveAnswers开始看
class Solution {
public:
int solve(string s, int k, char c)
{
int res = 0; // sum是要改变的字符数
for (int l = 0, r = 0, sum = 0; r < s.size(); r ++)
{
if (s[r] != c) sum ++; // 每次往前移动一位, 如果是要改变的字符 sum ++, 不是的话 不加, 尽可能保证窗口长度比较大
while (sum > k) // 保证 sum 一定 <= k
{
if (s[l] != c) sum --;
l ++;
}
res = max(res, r - l + 1); // r 和 l 是窗口的左右闭区间, 求窗口中元素的个数 r - l + 1
}
return res;
}
int maxConsecutiveAnswers(string answerKey, int k) {
// 改变'T'的 和 改变'F'的取最大值
int res = max(solve(answerKey, k, 'T'), solve(answerKey, k, 'F'));
return res;
}
};
总结
滑动窗口算法是一种用于解决子数组或子串问题的有效技巧.
常见类型:
-
固定长度的子数组/子串:
- 问题:找到固定长度的子数组或子串,并求其某些特征(如最大或最小值、平均值等)。
- 例子:给定一个数组和一个整数k,找到长度为k的子数组的最大平均值。
-
可变长度的子数组/子串:
- 问题:找到可变长度的子数组或子串,使其满足某些条件(如和等于某个值、包含某些字符等)。
- 例子:给定一个数组,找到和等于某个值的最长子数组。
-
最长或最短的子数组/子串:
- 问题:找到满足某些条件的最长或最短子数组或子串。
- 例子:给定一个字符串和一个整数k,找到包含最多k个不同字符的最长子串。
本题属于第三种, 满足某个条件的最长子数组
滑动窗口算法通常用于需要在线性时间内解决子数组或子串问题的场景。这些问题的特征通常包括寻找具有特定属性的最长或最短子数组/子串,以及满足某些条件的子数组/子串。这种技术通过动态调整窗口的大小,使得算法能在高效的时间复杂度内找到问题的解。
觉得写的不错的话, 点个赞吧~