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' 。
思路:
这道题的思路是使用滑动窗口,由于这里有K的字符的冗余,所以我们只需要记录下不是该字符的数目即可,当该数目超过K,说明当前遍历的字符串中的不是该字符的长度超出,那么需要将左边界右移。
class Solution:
def maxConsecutiveAnswers(self, answerKey: str, k: int) -> int:
# 计算ch的最大长度
def count(ch):
# count记录不是ch的数目,start为左边界,ans为最大长度,需要同步更新
count, left, ans = 0, 0, 0
for i in range(len(answerKey)):
count += answerKey[i] != ch
# 当count > K 时需要右移左边界
while count > k:
count -= answerKey[left] != ch
left += 1
# 更新长度,这里的长度为 当前遍历位置 - 开始位置 + 1,包含不是ch的最大长度
ans = max(ans, i - left + 1)
return ans
# 需要分别统计T和F的最大长度
return max(count("T"), count("F"))
前置问题
485、最大连续1的个数
给定一个二进制数组 nums
, 计算其中最大连续 1
的个数。
示例1:
输入:nums = [1,1,0,1,1,1]
输出:3
解释:开头的两位和最后的三位都是连续 1 ,所以最大连续 1 的个数是 3.
示例2:
输入:nums = [1,0,1,1,0,1]
输出:2
思路:
遍历数组,遇到为1的进行累加,遇到不为1的,缓存最大值并重置累加
class Solution:
def findMaxConsecutiveOnes(self, nums: List[int]) -> int:
ans, count = 0, 0
for i in range(len(nums)):
# 遇到1累加,不为1更新最大值,重置累加
if nums[i] == 1:
count += 1
else:
ans = max(ans, count)
count = 0
return max(ans, count)
1004、最大连续1的个数3
给定一个二进制数组 nums
和一个整数 k
,如果可以翻转最多 k
个 0
,则返回 数组中连续 1
的最大个数 。
示例1:
输入:nums = [1,1,1,0,0,0,1,1,1,1,0], K = 2
输出:6
解释:[1,1,1,0,0,1,1,1,1,1,1]
粗体数字从 0 翻转到 1,最长的子数组长度为 6。
示例2:
输入:nums = [0,0,1,1,0,0,1,1,1,0,1,1,0,0,0,1,1,1,1], K = 3
输出:10
解释:[0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1]
粗体数字从 0 翻转到 1,最长的子数组长度为 10。
思路:
滑动窗口并记录0的个数,如果0的个数大于k,那么左边界右移
class Solution:
def longestOnes(self, nums: List[int], k: int) -> int:
left, count, ans = 0, 0, 0
for i in range(len(nums)):
count += nums[i] == 0
# 0的数目大于k,左边界右移到下一个0的位置
while count > k:
count -= nums[left] == 0
left += 1
ans = max(ans, i - left + 1)
return ans