替换后的最长重复字符
难度:
标签:
题目描述
给你一个字符串 s
和一个整数 k
。你可以选择字符串中的任一字符,并将其更改为任何其他大写英文字符。该操作最多可执行 k
次。
在执行上述操作后,返回 包含相同字母的最长子字符串的长度。
示例 1:
输入:s = "ABAB", k = 2 输出:4 解释:用两个'A'替换为两个'B',反之亦然。
示例 2:
输入:s = "AABABBA", k = 1 输出:4 解释: 将中间的一个'A'替换为'B',字符串变为 "AABBBBA"。 子串 "BBBB" 有最长重复字母, 答案为 4。 可能存在其他的方法来得到同样的结果。
提示:
1 <= s.length <= 105
s
仅由大写英文字母组成0 <= k <= s.length
代码结果
运行时间: 51 ms, 内存: 16.0 MB
/*
* Problem: Given a string s and an integer k, you can change any character in the string
* to any other uppercase English letter up to k times. Return the length of the longest
* substring that contains the same letter after performing the above operations.
*
* Approach:
* - Use the sliding window technique to find the longest substring.
* - Use Java Streams to manage the counting of characters.
* - Track the maximum count of any character in the window.
* - If the current window size minus the max count is greater than k, shrink the window.
* - Update the maximum length whenever a valid window is found.
*/
import java.util.stream.IntStream;
public class Solution {
public int characterReplacement(String s, int k) {
int[] count = new int[26];
int maxCount = 0, maxLength = 0;
int left = 0;
for (int right = 0; right < s.length(); right++) {
count[s.charAt(right) - 'A']++;
maxCount = IntStream.of(count).max().orElse(0);
while (right - left + 1 - maxCount > k) {
count[s.charAt(left) - 'A']--;
left++;
}
maxLength = Math.max(maxLength, right - left + 1);
}
return maxLength;
}
}
解释
方法:
这个题解采用了滑动窗口的方法。首先定义两个指针l和r表示窗口的左右边界,并使用一个哈希表count来记录窗口内各字符的出现次数。变量max_str用来记录窗口中出现次数最多的字符的数量。在遍历字符串s的过程中,不断扩大窗口(右移r),并更新count和max_str。当窗口大小减去max_str的结果大于k时,说明窗口内无法通过k次替换达到全部相同的字符,此时需要左移l并相应地调整count。遍历结束后,窗口的大小即为结果。
时间复杂度:
O(n)
空间复杂度:
O(1)
代码细节讲解
🦆
在算法中,为什么选择滑动窗口作为解决方案,它与问题的性质有什么关联?
▷🦆
当窗口内字符最多的数量`max_str`被更新时,是否只考虑当前右指针`r`指向的字符,还是需要重新计算整个窗口中所有字符的出现频率?
▷🦆
如何确保在左指针`l`移动后,`max_str`(窗口中字符的最大频率)仍然是准确的,没有漏掉可能的新的最大频率?
▷🦆
算法中提到当`r - l + 1 - max_str > k`时,左指针需要移动。这个条件为何能确保窗口内的字符通过最多`k`次替换可以全部相同?
▷相关问题
最大连续1的个数 III
给定一个二进制数组 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。
提示:
1 <= nums.length <= 105
nums[i]
不是0
就是1
0 <= k <= nums.length