前言:题太多了TAT,只贴了部分我觉得比较好的题
32. 最长有效括号
class Solution {
public:
int longestValidParentheses(string s) {
int n = s.size();
s = " " + s;
vector<int> dp(n + 1, 0);
int ans = 0;
for (int i = 2; i <= n; i++) {
if (s[i] == '(') dp[i] = 0;
else {
if (s[i - 1] == '(') dp[i] = dp[i - 2] + 2;
else {
int pre = i - 2 - dp[i - 1];
if (s[pre + 1] == '(') dp[i] = dp[i - 1] + 2 + (pre > 0 ? dp[pre] : 0);
}
}
ans = max(ans, dp[i]);
}
return ans;
}
};
分类讨论:
si == '(' : 肯定dpi = 0
si == ‘)’: 看si - 1的是不是'(', 如果不是再往前找...
注意dp[pre]会连接起来
152. 乘积最大子数组
class Solution {
public:
int maxProduct(vector<int>& a) {
int n = a.size();
vector<vector<int>> dp(n, vector<int>(2, 0));
dp[0][0] = dp[0][1] = a[0];
int ans = a[0];
for (int i = 1; i < n; i++) {
if (!a[i]) dp[i][1] = dp[i][0] = 0;
else if (a[i] > 0) {
if (dp[i - 1][1] > 0) dp[i][1] = dp[i - 1][1] * a[i];
else dp[i][1] = a[i];
if (dp[i - 1][0] <= 0) dp[i][0] = dp[i - 1][0] * a[i];
else dp[i][0] = a[i];
}
else {
if (dp[i - 1][0] <= 0) dp[i][1] = dp[i - 1][0] * a[i];
else dp[i][1] = a[i];
if (dp[i - 1][1] > 0) dp[i][0] = dp[i - 1][1] * a[i];
else dp[i][0] = a[i];
}
ans = max({ ans, dp[i][0], dp[i][1] });
}
return ans;
}
};
分类大讨论,维护以i为结尾的乘积最大值和最小值即可
72. 编辑距离
class Solution {
public:
int minDistance(string s1, string s2) {
int n = s1.size(), m = s2.size();
if (!n) {
return m;
}
if (!m) {
return n;
}
s1 = " " + s1;
s2 = " " + s2;
vector<vector<int>> dp(n + 1, vector<int>(m + 1, 1e5));
dp[0][0] = 0;
for (int i = 1; i <= n; i++) dp[i][0] = i;
for (int i = 1; i <= m; i++) dp[0][i] = i;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
int t = min({ dp[i - 1][j - 1], dp[i - 1][j], dp[i][j - 1] }) + 1;
dp[i][j] = min(dp[i][j], t);
if (s1[i] == s2[j]) dp[i][j] = min(dp[i][j], dp[i - 1][j - 1]);
}
}
return dp[n][m];
}
};
5. 最长回文子串
class Solution {
public:
string longestPalindrome(string s) {
string str = "";
str.push_back('$');
str.push_back('#');
for (auto ch : s) {
str.push_back(ch);
str.push_back('#');
}
int n = str.size() - 1;
vector<int> d(n + 10, 0);
d[1] = 1;
for (int i = 2, l, r = 1; i <= n; i++) {
if (i <= r) d[i] = min(d[l + r - i], r - i + 1);
while (str[i - d[i]] == str[i + d[i]]) d[i]++;
if (i + d[i] - 1 > r) {
l = i - d[i] + 1;
r = i + d[i] - 1;
}
}
int ans = 0;
int p = 0;
string ss = "";
for (int i = 1; i <= n; i++) {
if (ans < d[i] - 1) {
ans = d[i] - 1;
p = i - d[i] + 1;
}
}
for (int i = p; ans > 0 ; i++) {
if (str[i] != '#') {
ss += str[i];
ans--;
}
}
return ss;
}
};