考试的最大困扰度-LeetCode
2024. 考试的最大困扰度
🎯 问题描述(来源于LeetCode)
描述:
一位老师正在出一场判断题测试,其中每道题的答案都是 ‘T’ (真) 或 ‘F’ (假)。
给你一个字符串 answerKey,其中 answerKey[i] 是第 i 题的正确答案。
同时给你一个整数 k,表示你最多可以执行 k 次操作。
每次操作你可以将任意一题的答案从 ‘T’ 改为 ‘F’,或者从 ‘F’ 改为 ‘T’。
请你返回在不超过 k 次操作的情况下,最大连续 ‘T’ 或者 ‘F’ 的数目。
说明:
-
这是一个不定长滑动窗口问题。
-
题目要求最大化连续相同字符的长度,这意味着我们需要找到一个子串,其中少数派字符的数量不超过
k(因为我们可以把少数派改成多数派)。 -
策略:分别计算“将 ‘F’ 改为 ‘T’”和“将 ‘T’ 改为 ‘F’”两种情况下的最大长度,取最大值。
-
示例:
-
示例 1:
1 | 输入:answerKey = "TTFF", k = 2 |
- 示例 2:
1 | 输入:answerKey = "TFFT", k = 1 |
💻 解题思路
思路1:双向滑动窗口
思路1:代码实现
1 | class Solution: |
思路1:📊 性能分析
- 时间复杂度:
- 其中 是字符串
answerKey的长度。 - 虽然代码中有两个
for循环,但它们是顺序执行的,且每个循环内部都是线性的滑动窗口操作。总时间复杂度为 。
- 其中 是字符串
- 空间复杂度:
- 哈希表
T_k和F_k最多存储 2 个键值对(‘T’ 和 ‘F’),因此空间复杂度是常数级别。
- 哈希表
思考
-
问题拆解:
- 题目要求“连续 ‘T’ 或者 ‘F’”,这暗示我们需要分别考虑两种目标情况。
- 情况 A:目标是全 ‘T’。这意味着窗口内最多允许有
k个 ‘F’(作为被替换的对象)。 - 情况 B:目标是全 ‘F’。这意味着窗口内最多允许有
k个 ‘T’。
-
滑动窗口逻辑:
- 在第一次遍历中,
T_k["F"]记录了当前窗口内 ‘F’ 的数量。 while T_k["F"] > k:保证了我们只保留那些可以通过k次操作变成全 ‘T’ 的子串。- 第二次遍历同理,只是监控对象变成了 ‘T’。
- 在第一次遍历中,
-
代码结构:
- 代码重复了两次几乎相同的逻辑,这是解决此类“二选一”最值问题的常用且清晰的方法。
- 也可以将其封装成一个辅助函数来减少代码重复,但目前的写法直观易懂。
-
变量命名:
T_k和F_k的命名略显简略,实际上它们分别代表“为了变成 T 而统计的计数器”和“为了变成 F 而统计的计数器”。ans_T和ans_F分别代表这两种策略下的最优解。
思路2:单趟滑动窗口(巧妙解法)
描述:
尝试在一次遍历中同时维护 ‘T’ 和 ‘F’ 的计数,并通过一个 while 循环来处理两种情况。
思路2:代码实现
1 | class Solution: |
思路2:📊 性能分析
- 时间复杂度:
- 其中 是字符串
answerKey的长度。
- 其中 是字符串
- 空间复杂度:
- 哈希表最多存储 2 个键值对(‘T’ 和 ‘F’),因此空间复杂度是常数级别。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 笺札!






