剑指 Offer II 017. 含有所有字符的最短字符串
hard题(时间击败100%)
双指针(
j
j
j 用来扩展字符串,
i
i
i 用来减短字符串),时间复杂度
O
(
n
)
O(n)
O(n)
class Solution {
public:
string minWindow(string s, string t) {
int n = s.size(), m = t.size();
int len = 0x3f3f3f3f;
string res;
int tst[200] = {0}; //分别标记字符数量
int tcnt = 0; //不同的字符数
for(int i = 0; i < m; i++) {
if(!tst[t[i]]) tcnt++;
tst[t[i]]++;
}
int sst[200] = {0}; //分别标记字符数量
bool st[200] = {0}; //标记s子串已经大于等于t中的字符
int i = 0, j = 0, scnt = 0; //scnt为st数组为true的个数
while(j < n) {
if(tst[s[j]] != 0) {
stst[s[j]]++;
if(!st[s[j]] && sst[s[j]] >= tst[s[j]]) {
scnt++;
st[s[j]] = true;
}
}
if(scnt == tcnt) {
//s子串包含了t中所有字符,开始移动i来减短子串长度
while(!tst[s[i]] || stst[s[i]] - 1 >= tst[s[i]]) {
stst[s[i++]]--;
}
if(len > j-i+1) {
len = j-i+1;
res = s.substr(i,len);
}
}
j++;
}
return res;
}
};
剑指 Offer II 018. 有效的回文
简单回文串
class Solution {
public:
bool isPalindrome(string s) {
int n = s.size();
string tmp;
for(char c : s) {
if(c >= '0' && c <= '9') tmp += c;
else if(c >= 'a' && c <= 'z') tmp += c;
else if(c >= 'A' && c <= 'Z') tmp += (char)(c+32);
}
n = tmp.size();
for(int i = 0; i < n/2; i++)
if(tmp[i] != tmp[n-i-1])
return false;
return true;
}
};
比普通回文串复杂一些,好的写法抽象分离冗余的模块
class Solution {
public:
bool check(string &s, int l,int r) {
while(l < r) {
if(s[l] != s[r]) return false;
else l++,r--;
}
return true;
}
bool validPalindrome(string s) {
int i = 0, j = s.size()-1;
int idx1 = -1, idx2 = -1;
while(i < j) {
if(s[i] == s[j]) {
i++,j--;
} else {
return check(s,i+1,j) || check(s,i,j-1);
}
}
return true;
}
};
剑指 Offer II 020. 回文子字符串的个数
字符串+DP
O ( n 2 ) O(n^2) O(n2)做法
class Solution {
public:
int countSubstrings(string s) {
int n = s.size();
int cnt = 0;
bool st[1010][1010] = {0};
for(int i = 0; i < n; i++) {
st[i][i] = true; cnt++;
for(int j = 0; j < i; j++){
if(s[j] == s[i]) {
if(i-j+1 > 2 && st[j+1][i-1] != true) continue;
cnt++, st[j][i] = true;
}
}
}
return cnt;
}
};
O
(
n
)
O(n)
O(n)dp做法
参考:https://leetcode.cn/problems/a7VOhD/solution/hui-wen-zi-zi-fu-chuan-de-ge-shu-by-leet-ejfv/
class Solution {
public:
int countSubstrings(string s) {
int n = s.size();
string t = "$#";
for (const char &c: s) {
t += c;
t += '#';
}
n = t.size();
t += '!';
auto f = vector <int> (n);
int iMax = 0, rMax = 0, ans = 0;
for (int i = 1; i < n; ++i) {
// 初始化 f[i]
f[i] = (i <= rMax) ? min(rMax - i + 1, f[2 * iMax - i]) : 1;
// 中心拓展
while (t[i + f[i]] == t[i - f[i]]) ++f[i];
// 动态维护 iMax 和 rMax
if (i + f[i] - 1 > rMax) {
iMax = i;
rMax = i + f[i] - 1;
}
// 统计答案, 当前贡献为 (f[i] - 1) / 2 上取整
ans += (f[i] / 2);
}
return ans;
}
};