
题目一:至少有 K 个重复字符的最长子串
题目解析解题代码
法一:递归分治法二:枚举类型的滑动窗口 题目二:最长的美好子字符串
题目解析解题代码
方法一:位运算+暴力遍历方法二:递归分治
个人网站观看更佳
395. 至少有 K 个重复字符的最长子串
题目解析有两种方法:
class Solution {
public:
int dfs(string& s,int l,int r,int k){
int cnt[26] = {0};
for(int i=l;i<=r;i++){//计算字符的次数方便计算ban掉的字符类型
cnt[s[i]-'a']++;
}
char split = 0;
for(int i=0;i<26;i++){
if(cnt[i]!=0&&cnt[i]r)
break;//说明全是被ban的字符
int start = l;
while(l<=r&&s[l]!=split){//计算本次分段的长度(结束位置)
l++;
}
int length = dfs(s,start,l-1,k);
ret = max(ret,length);
}
return ret;
}
int longestSubstring(string s, int k) {
return dfs(s,0,s.size()-1,k);
}
};
法二:枚举类型的滑动窗口
class Solution {
public:
int longestSubstring(string s, int k) {
int n = s.size();
int cnt[26]{0};//用于记录窗口内字符的出现次数
int maxLen = 0;
for(int i=1;i<=26;i++){
memset(cnt,0,sizeof(cnt));
for(int l=0,r=0,sum=0,tot=0;ri){ //达到收缩窗口条件,因为窗口内的种类数限制为i个
int dup = (s[l++]-'a');
cnt[dup]--;
if(cnt[dup]==0) //种类数此时需要-1
tot--;
if(cnt[dup]==k-1)//有效种类数-1
sum--;
}
if(sum==tot)
maxLen = max(maxLen,r-l+1);
}
}
return maxLen;
}
};
题目二:最长的美好子字符串
最长的美好子字符串
题目解析这题虽然由于数据量的关系,被划分为简单题,但实际上完全不亚于第一题。甚至还得用上一些位运算的思想。
这题我会的做法只有两种:
class Solution {
public:
string longestNiceSubstring(string s) {
int sz = s.size();
int start,len=0;
for(int i=0;ilen)){
start = i;
len = j-i+1;
}
}
}
return len==0?"":s.substr(start,len);
}
};
方法二:递归分治
class Solution {
public:
void dfs(string &s, int l, int r, pair &ret) {
int lower = 0, upper = 0;
for (int i = l; i <= r; i++) {
if (islower(s[i])) {
lower |= (1 << (s[i] - 'a'));
} else {
upper |= (1 << (s[i] - 'A'));
}
}
if (lower == upper) {//我之前这里的判断条件导致了无限循环,一旦满足第一个条件,但不满足第二个条件,就发生无限循环!!!所以注意放到下面去
if (r - l + 1 > ret.second) {
ret.first = l;
ret.second = r - l + 1;
}
return;
}
int valid = lower & upper;//这两的交集代表大小写都出现的类型,为符合条件的类型,而被ban的就是不处于这里面的字符类型
int start;
while (l <= r) {
while (l <= r && !(valid & (1 << (tolower(s[l]) - 'a')))) {//让start处于符合条件的类型
l++;
}
if (l > r)
break;
start = l;
while (l <= r && (valid & (1 << (tolower(s[l]) - 'a')))) {//得到符合条件的分段右端点
l++;
}
dfs(s, start, l - 1, ret);
}
}
string longestNiceSubstring(string s) {
pair ret{0, 0};
dfs(s, 0, s.size() - 1, ret);
return s.substr(ret.first, ret.second);
}
};