【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
posted @ 2024-09-02 16:05  TICSMC  阅读(25)  评论(0)    收藏  举报