题目链接
代码随想录文章讲解链接
用时:8m48s
先计算两个字符串的最长公共子序列的长度L,答案为两字符串长度之和减去两倍的L。
class Solution {
public:
int minDistance(string word1, string word2) {
vector<int> dp(word2.length() + 1, 0);
int tmp1 = 0, tmp2 = 0;
for (int i = 1; i <= word1.length(); ++i) {
tmp1 = dp[0];
for (int j = 1; j <= word2.length(); ++j) {
tmp2 = dp[j];
if (word1[i - 1] == word2[j - 1]) dp[j] = tmp1 + 1;
else dp[j] = max(dp[j - 1], dp[j]);
tmp1 = tmp2;
}
}
return word1.length() + word2.length() - 2 * dp[word2.length()];
}
};
无。
无。
题目链接
代码随想录文章讲解链接
用时:26m28s
dp数组:二维dp数组,dp[i][j]表示word1[:i]和word2[:j]的最小编辑距离。
状态转移:
words1[i] == words2[j]
:
dp[i][j] = myMin(dp[i - 1][j - 1], dp[i][j - 1] + 1, dp[i - 1][j] + 1)
。words1[i] != words2[j]
:
dp[i][j] = myMin(dp[i - 1][j - 1] + 1, dp[i][j - 1] + 1, dp[i - 1][j] + 1)
。class Solution {
public:
int minDistance(string word1, string word2) {
int len1 = word1.length(), len2 = word2.length();
vector<vector<int>> dp(len1 + 1, vector<int>(len2 + 1, 0)); // dp数组
for (int j = 1; j <= len2; ++j) dp[0][j] = j; // dp数组初始化
for (int i = 1; i <= len1; ++i) {
dp[i][0] = i; // dp数组初始化
for (int j = 1; j <= len2; ++j) {
if (word1[i - 1] == word2[j - 1]) dp[i][j] = myMin(dp[i - 1][j - 1], dp[i][j - 1] + 1, dp[i - 1][j] + 1);
else dp[i][j] = myMin(dp[i - 1][j - 1], dp[i][j - 1], dp[i - 1][j]) + 1;
}
}
return dp[len1][len2];
}
int myMin(int a, int b, int c) {
int res = a;
if (b < res) res = b;
if (c < res) res = c;
return res;
}
};
用时:7m5s
方法一空间优化。
class Solution {
public:
int minDistance(string word1, string word2) {
int len1 = word1.length(), len2 = word2.length();
vector<int> dp(len2 + 1, 0);
int tmp1 = 0, tmp2 = 0;
for (int j = 1; j <= len2; ++j) dp[j] = j;
for (int i = 1; i <= len1; ++i) {
tmp1 = dp[0];
dp[0] = i;
for (int j = 1; j <= len2; ++j) {
tmp2 = dp[j];
if (word1[i - 1] == word2[j - 1]) dp[j] = myMin(tmp1, dp[j - 1] + 1, dp[j] + 1);
else dp[j] = myMin(tmp1, dp[j - 1], dp[j]) + 1;
tmp1 = tmp2;
}
}
return dp[len2];
}
int myMin(int a, int b, int c) {
int res = a;
if (b < res) res = b;
if (c < res) res = c;
return res;
}
};
无。
无。
题目链接
代码随想录文章讲解链接
用时:29m58s
dp数组:二维dp数组,dp[i][j]表示以第i至j个字符组成的子串是否是回文串。
状态转移:
s[i] != s[j]
时,第i至j个字符组成的子串肯定不是回文串。s[i] == s[j]
时,如果第i+1至j-1个字符组成的子串是回文串,则第i至j个字符组成的子串也是,否则不是。class Solution {
public:
int countSubstrings(string s) {
int len = s.length();
vector<vector<bool>> dp(len, vector<bool>(len, false));
int res = 0;
for (int i = 0; i < len; ++i) dp[i][i] = true;
for (int j = 0; j < len; ++j) {
for (int i = 0; i < j; ++i) {
if (s[i] == s[j]) dp[i][j] = i + 1 > j - 1 ? true : dp[i + 1][j - 1];
res += dp[i][j];
}
}
return res + len;
}
};
用时:5m47s
方法一空间优化。
class Solution {
public:
int countSubstrings(string s) {
int len = s.length();
vector<bool> dp(len, false);
int res = 0;
for (int j = 0; j < len; ++j) {
for (int i = 0; i <= j; ++i) {
if (s[i] == s[j]) dp[i] = i + 1 > j - 1 ? true : dp[i + 1];
else dp[i] = false;
res += dp[i];
}
}
return res;
}
};
遍历字符串,统计以每个字符或每两个字符为中心的回文子串的数量,统计回文子串时用双指针。
class Solution {
public:
int countSubstrings(string s) {
int len = s.length();
int res = 0;
for (int i = 0; i < len; ++i) {
res += extend(s, i, i, len);
res += extend(s, i, i + 1, len);
}
return res;
}
// 双指针
int extend(const string& s, int i, int j, int len) {
int res = 0;
while (i >= 0 && j < len && s[i--] == s[j++]) ++res;
return res;
}
};
无。
无。
题目链接
代码随想录文章讲解链接
用时:33m32s
dp数组:二维dp数组,dp[i][j]表示第i至j个字符组成的子串中最长回文子序列(LPS)的长度。
状态转移:对于第i至j个字符组成的子串,我们要基于第i+1至j-1个字符组成的子串。
s[i] == s[j]
:对于第i+1至j-1个字符组成的子串来说,两头的字符相等,所以LPS的长度+2,即dp[i][j] = dp[i + 1][j - 1] + 2
。s[i] != s[j]
:对于第i+1至j-1个字符组成的子串来说,两头的字符不一样,同时增加他们两个无法使LPS的长度增加,考虑只增加一个,分别是只增加左边的字符和只增加右边的字符,LPS的长度为两者中的最大值,即dp[i][j] = max(dp[i + 1][j], dp[i][j - 1])
。class Solution {
public:
int longestPalindromeSubseq(string s) {
int len = s.length();
vector<vector<int>> dp(len, vector<int>(len, 0));
for (int j = 0; j < len; ++j) {
dp[j][j] = 1;
for (int i = j - 1; i >= 0; --i) {
dp[i][j] = s[i] == s[j] ? dp[i + 1][j - 1] + 2 : max(dp[i + 1][j], dp[i][j - 1]);
}
}
return dp[0][len - 1];
}
};
用时:4m3s
方法一用滚动数组优化空间复杂度。
class Solution {
public:
int longestPalindromeSubseq(string s) {
int len = s.length();
vector<int> dp(len, 0);
int tmp1 = 0, tmp2 = 0;
for (int j = 0; j < len; ++j) {
tmp1 = dp[j];
dp[j] = 1;
for (int i = j - 1; i >= 0; --i) {
tmp2 = dp[i];
dp[i] = s[i] == s[j] ? tmp1 + 2 : max(dp[i + 1], dp[i]);
tmp1 = tmp2;
}
}
return dp[0];
}
};
无。
无。
题目链接
代码随想录文章讲解链接
用时:16m43s
class Solution {
public:
vector<int> dailyTemperatures(vector<int>& temperatures) {
int size = temperatures.size();
vector<int> res(size, 0);
stack<pair<int, int>> stk;
stk.push(pair<int, int>(temperatures[size - 1], size - 1));
for (int i = size - 2; i >= 0; --i) {
while (!stk.empty() && temperatures[i] >= stk.top().first) stk.pop();
res[i] = stk.empty() ? 0 : stk.top().second - i;
stk.push(pair<int, int>(temperatures[i], i));
}
return res;
}
};
其实不用存具体元素,只用存下标。
class Solution {
public:
vector<int> dailyTemperatures(vector<int>& temperatures) {
int size = temperatures.size();
vector<int> res(size, 0);
stack<int> stk;
stk.push(size - 1);
for (int i = size - 2; i >= 0; --i) {
while (!stk.empty() && temperatures[i] >= temperatures[stk.top()]) stk.pop();
res[i] = stk.empty() ? 0 : stk.top() - i;
stk.push(i);
}
return res;
}
};
无。
无。
动态规划,完结撒花!!!
拖了好久,终于刷完了动态规划,最近忙比赛,时间太紧了,基本没什么时间刷题。