一个不太难的题,不算dp,最早写的一版200多ms才A掉
const int SZ = 26;
class Solution {
public:
int longestSubstring(string s, int t) {
if (!s.size() || t > s.size()) return 0;
int prefix[26][s.size()];
int suffix[26][s.size()];
int dp[s.size()][s.size()];
for (int i = 0; i < s.size(); i++) {
for(int j = 0; j < 26; j++) {
prefix[j][i] = (s[i] - 'a')==j;
if (i != 0)
prefix[j][i] += prefix[j][i-1];
}
}
for (int i = s.size() - 1; i >= 0; i--) {
for (int j = 0; j < 26; j++) {
suffix[j][i] = ( (s[i] - 'a')==j );
if (i != s.size()-1)
suffix[j][i] += suffix[j][i+1];
}
}
int ans = 0, en = s.size()-1;
for (int i = 0; i < s.size(); i++) {
for (int j = i; j < s.size(); j++) {
bool ok = true;
int k = s[i] - 'a';
int cnt = prefix[k][j] + suffix[k][i] - prefix[k][en];
if (cnt && cnt < t) continue;
for (int k = 0; k < 26; k++) {
int cnt = prefix[k][j] + suffix[k][i] - prefix[k][en];
if (cnt && cnt < t) {
ok = false;
}
// if (cnt >= t) {
// cout << "cnt:" << cnt << " c:" << (char)('a' + k) << endl;
// }
}
if (ok) {
ans = max(ans, j - i + 1);
// cout << "i:" << i << " j:" << j << endl;
}
}
}
return ans;
}
};
然后想了下,可以省略一些操作,使用一个数组bigger,维护>=k的字母的长度和。160多ms过掉。
const int SZ = 26;
class Solution {
public:
int longestSubstring(string s, int t) {
if (!s.size() || t > s.size()) return 0;
int prefix[26][s.size()];
int bigger[s.size()];
for (int i = 0; i < s.size(); i++) {
for(int j = 0; j < 26; j++) {
prefix[j][i] = (s[i] - 'a')==j;
if (i != 0)
prefix[j][i] += prefix[j][i-1];
}
}
int ans = 0, en = s.size()-1;
for (int i = 0; i < s.size(); i++) {
// memset(bigger, sizeof(bigger), 0);
for (int j = i; j < s.size(); j++) {
bigger[j] = j == i ? 0 : bigger[j-1];
// bool ok = true;
int k = s[j] - 'a';
int cnt = prefix[k][j];
if (i) cnt -= prefix[k][i - 1];
if (cnt < t) {
continue;
} else {
if (cnt == t) {
bigger[j] += t;
} else {
bigger[j] += 1;
}
}
if (bigger[j] < j - i + 1) continue;
ans = max(ans, j - i + 1);
}
}
return ans;
}
};
然后看了下答案,大概170ms过的,用了mask位运算来记录有多少个字母>=k, 思路也很简单,就是每个位表示是不是>=k,是为1,否则为0,这样的话符合更新ans条件的时候mask == 0 有意思
class Solution {
public:
int longestSubstring(string s, int k) {
int max_len = 0;
for (int first = 0; first+k <= s.size();) {
int count[26] = {0};
int mask = 0;
int max_last = first;
for (int last = first; last < s.size(); ++last) {
int i = s[last] - 'a';
count[i]++;
if (count[i]<k) mask |= (1 << i);
else mask &= (~(1 << i));
if (mask == 0) {
max_len = max(max_len, last-first+1);
max_last = last;
}
}
first = max_last + 1;
}
return max_len;
}
};