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 * 104
answerKey[i]
要么是'T'
,要么是'F'
1 <= k <= n
解题分析及思路:
方法:滑动窗口
思路:
以双指针的思想来实现滑动窗口。
- 初始化:定义两个指针
left
和right
,分别指向滑动窗口的左边界和右边界。 - 在寻找的过程中,通过扩张和伸缩窗口,找到窗口内的最大连续相同字符数目。
窗口内的最大连续字符数目,可以通过维护两个计数器 tCount
和 fCount
来计算。
- 扩张:当
tCount
和fCount
都任意小于k
,则说明窗口内的字符数目是有效的。 - 收缩:当
tCount
和fCount
都大于等于k
,则说明窗口内的字符数目已经无效,需要收缩窗口。 - 每次收缩后,窗口将达到最大值,即
tCount + fCount
,此时可以更新答案。
func maxConsecutiveAnswers(answerKey string, k int) int {
var tCount, fCount int
var left, right = 0, 0
var ans = 0
for right < len(answerKey) {
// 扩张
if answerKey[right] == 'T' {
tCount++
} else {
fCount++
}
right++
// 收缩
for tCount > k && fCount > k {
if answerKey[left] == 'T' {
tCount--
} else {
fCount--
}
left++
}
ans = max(ans, tCount+fCount)
}
return ans
}
func max(a, b int) int {
if a > b {
return a
}
return b
}
复杂度:
- 时间复杂度:O(N)
- 空间复杂度:O(1)
执行结果:
- 执行耗时:4 ms,击败了98.84% 的Go用户
- 内存消耗:5.2 MB,击败了73.26% 的Go用户