【Leetcode】2024. 考试的最大困扰度_1643
题目
2024.考试的最大困扰度
一位老师正在出一场由 n 道判断题构成的考试,每道题的答案为 true (用 'T' 表示)或者 false (用 'F' 表示)。老师想增加学生对自己做出答案的不确定性,方法是 最大化 有 连续相同 结果的题数。(也就是连续出现 true 或者连续出现 false)。
给你一个字符串 answerKey ,其中 answerKey[i] 是第 i 个问题的正确结果。除此以外,还给你一个整数 k ,表示你能进行以下操作的最多次数:
每次操作中,将问题的正确答案改为 'T' 或者 'F' (也就是将 answerKey[i] 改为 'T' 或者 'F' )。
请你返回在不超过 k 次操作的情况下,最大 连续 'T' 或者 'F' 的数目。
前言
前缀和+二分法 以及滑动窗口两种解法
题目的难度不算大,两个方法的时间复杂度分别是\(O(n\ log\ n)\)和\(O(n)\)
思路
1. 前缀和+二分 \(O(n\ log\ n)\)
当k增大的时候,得到的结果也就是最大 连续 'T' 或者 'F' 的数目 只会是不变或者增大,也就是说,k增大的时候,结果也是不减小的,即递增的关系(广义的递增)
那么这个时候就可以考虑使用二分法了,二分的是k。
此时就考虑给定一个子串,如何计算出需要使用的变换次数k。对于这个子串,知道其中T的个数或者F的个数,那么此时要么把T全部变为F,要么反过来。
而快速的计算出子串中T\F的个数,就可以使用前缀和了。
class Solution:
def maxConsecutiveAnswers(self, answerKey: str, k: int) -> int:
sub = [0]
for x in answerKey:
sub.append(sub[-1]+(x=='T'))
n = len(answerKey)
def check(v):
# 判断得到v 长度的连续 'T' 或者 'F'使用的交换次数
res = n
for i in range(n-v+1):
temp = sub[i+v]-sub[i]
res = min(res,v-temp,temp)
return res
return bisect_right(list(range(1,n+1)), k,key=check)
2. 滑动窗口\(O(n)\)
考虑使用滑动窗口,当前窗口内保证使用的变换次数不超过k,窗口右移动的时候,如果超过了k,左边界就移动到合适为止。
class Solution:
def maxConsecutiveAnswers(self, answerKey: str, k: int) -> int:
n = len(answerKey)
l = 0
cnt = 0
ans = 0
for r in range(n):
cnt += answerKey[r]=='T'
while cnt+k<r-l+1 and cnt>k:
cnt-=answerKey[l]=='T'
l+=1
ans = max(ans, r-l+1)
return ans

浙公网安备 33010602011771号