力扣424-替换后的最长重复字符

  |  

摘要: 力扣 424,双指针+哈希表

【对算法,数学,计算机感兴趣的同学,欢迎关注我哈,阅读更多原创文章】
我的网站:潮汐朝夕的生活实验室
我的公众号:算法题刷刷
我的知乎:潮汐朝夕
我的github:FennelDumplings
我的leetcode:FennelDumplings


各位好,本文我们看一个双指针的问题,指针推进的过程中用哈希表维护窗口内的值。


$1 题目

给你一个仅由大写英文字母组成的字符串,你可以将任意位置上的字符替换成另外的字符,总共可最多替换 k 次。在执行上述操作后,找到包含重复字母的最长子串的长度。

注意:

1
字符串长度 和 k 不会超过 1e4。

示例 1:
输入:
s = “ABAB”, k = 2
输出:
4
解释:
用两个’A’替换为两个’B’,反之亦然。
示例 2:
输入:
s = “AABABBA”, k = 1
输出:
4
解释:
将中间的一个’A’替换为’B’,字符串变为 “AABBBBA”。
子串 “BBBB” 有最长重复字母, 答案为 4。

$2 题解

算法: 单串单向双指针

维护一个哈希表统计窗口内各个字符的出现次数。

推进 right, 更新哈希表,检查窗口是否合法,如果不合法就 break,否则继续推进 right。

此时 [left, right - 1] 是合法范围,更新答案。

然后推进 left 并更新哈希表,直到窗口合法。

代码 (C++)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
class Solution {
public:
int characterReplacement(string s, int k) {
vector<int> cnts(26);
int n = s.size();
int left = 0, right = 0;
int ans = 0;
while(right < n)
{
while(right < n)
{
++cnts[s[right] - 'A'];
if(!check(cnts, k, left, right))
break;
++right;
}
ans = max(ans, right - left);
if(right == n) break;
while(!check(cnts, k, left, right))
{
--cnts[s[left] - 'A'];
++left;
}
++right;
}
return ans;
}

private:
bool check(const vector<int>& cnts, int k, int l, int r)
{
int max_cnt = 0;
for(int c: cnts)
{
max_cnt = max(max_cnt, c);
}
int len = r - l + 1;
return len - max_cnt <= k;
}
};

Share