1143.最长公共子序列
本题与 718.最长重复子数组 的思路基本一样,都是求两个序列的重复字串。不同之处在于,本题允许子序列可以不连续。在递归公式上,需要进行改进。
当 text1[i - 1] == text2[j - 1] 时,dp[i][j] = dp[i - 1][j - 1] + 1,即当前两个字符串中对应的字符相同,公共子序列的长度等于前一个字符串处公共子序列的长度加 1。当不满足上述条件时,在当前字符处最长公共子序列的长度,应该等于在 text1 或 text2 中以前一个字符结尾的字符串对应的最长公共子序列的最大值。
class Solution {
public:
int longestCommonSubsequence(string text1, string text2) {
auto dp = vector<vector<int>> (text1.size() + 1, vector<int>(text2.size() + 1, 0));
int result = 0;
for (int i = 1; i <= text1.size(); ++i) {
for (int j = 1; j <= text2.size(); ++j) {
if (text1[i - 1] == text2[j - 1]) dp[i][j] = dp[i - 1][j - 1] + 1;
else dp[i][j] = dp[i][j - 1], dp[i - 1][j]);
result = max(result, dp[i][j]);
}
}
return result;
}
};
1035.不相交的线
与上一题思路类似,区别在于递推公式,在数组 nums1 中的数字 nums1[i] 如果能与 nums[j] 相连接,当前 dp[i] 两种选择,连接和不连接,取最大值即可。
class Solution {
public:
int maxUncrossedLines(vector<int> &nums1, vector<int> &nums2) {
int len1 = nums1.size(), len2 = nums2.size();
if (len1 == 0 || len2 == 0) return 0;
auto dp = vector<vector<int>> (len1 + 1, vector<int> (len2 + 1, 0));
int result = 0;
for (int i = 1; i <= len1; ++i) {
for (int j = 1; j <= len2; ++j) {
if (nums1[i - 1] == nums2[j - 1]) dp[i][j] = max(dp[i][j], dp[i - 1][j - 1] + 1);
else dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
result = max(result, dp[i][j]);
}
}
return result;
}
};
53.最大子数组和
class Solution {
public:
int maxSubArray(vector<int> &nums) {
if (nums.size() == 0) return 0;
auto dp = vector<int> (nums.size(), 0);
dp[0] = nums[0];
int result = dp[0];
for (int i = 1; i < nums.size(); ++i) {
dp[i] = max(dp[i], dp[i - 1] + nums[i]);
result = max(result, dp[i]);
}
return result;
}
};