Given a string text, we are allowed to swap two of the characters in the string.
Find the length of the longest substring with repeated characters.
Input: "ababa" Output: 3
Input: "aaabaaa" Output: 6
Input: "aaabbaaa" Output: 4
Input: "aaaaa" Output: 5
Input: "abcdef" Output: 1
这道题就是先把string转成字符加数字的形式,比如 “aaabaaa” 转成 (a, 3), (b, 1), (a, 3) 然后三种方式计算可能的最长的长度:
- 分成一段一段的过程中,就可以计算每一段长度,更新 max_len;
- 检查有没有单个字符分隔开两段相同字符(比如 X)的情况,这种情况如果还有多余的 X,就可以交换过来连接两段了,新的长度是两段的和 + 1,如果没有多余的 X,那就让最边上 X 交换过来,长度是两段的和;
- 对于每一个字符 X 的最大分段,看有没有多余的 X 存在,这样就可以多 1 的长度了。
AC代码如下:
class Solution {
public:
int digit_total_cnt[26], digit_max_len[26];
int maxRepOpt1(string text) {
vector<pair<int, int>> seq;
int max_len = 1;
for (int i = 0; i < text.length(); ){
int cnt = 1, c_num = text[i] - 'a';
while (text[i + cnt] == text[i])
++cnt;
seq.emplace_back(c_num, cnt);
i += cnt;
digit_total_cnt[c_num] += cnt;
digit_max_len[c_num] = max(digit_max_len[c_num], cnt);
max_len = max(max_len, cnt);
}
// 检查有没有一个字符将字母 X 的两段分开,且还有多余的 X 存在
for (int i = 1; i < seq.size() - 1; ++i)
if (seq[i].second == 1 && seq[i - 1].first == seq[i + 1].first){
int tmp = seq[i - 1].second + seq[i + 1].second;
if (tmp != digit_total_cnt[seq[i - 1].first])
++tmp;
max_len = max(max_len, tmp);
}
// 对每个单独字母 X 的最大连续段,检查有没有多余的 X
for (int i = 0; i < 26; ++i)
if (digit_max_len[i] != digit_total_cnt[i])
max_len = max(max_len, digit_max_len[i] + 1);
return max_len;
}
};