- 300. 最长递增子序列
dp[i]代表以nums[i]结尾的递增子序列的最长长度 dp数组初始化为1,因为每一个数字本身就是一个子序列且是递增子序列,长度为1 AC代码:
class Solution {
public:
int lengthOfLIS(vector<int>& nums) {
int n = nums.size();
// 以nums[i]结尾的递增子序列的最长长度
vector<int> dp(n, 1);
int res = 0;
for (int i = 0; i < n; ++i) {
for (int j = 0; j < i; ++j) {
if (nums[j] < nums[i]) {
dp[i] = max(dp[i], dp[j] + 1);
}
}
res = max(res, dp[i]);
}
return res;
}
};
dp[i]代表以nums[i]结尾的最长连续递增子序列的长度
因为连续,所以nums[i]的前一个必定是nums[i-1],因此当nums[i] > nums[i - 1]时,dp[i] = dp[i - 1] + 1;否则dp[i] = 1
class Solution {
public:
int findLengthOfLCIS(vector<int>& nums) {
int n = nums.size();
vector<int> dp(n, 1);
int res = 1;
for (int i = 1; i < n; ++i) {
if (nums[i] > nums[i - 1]) {
dp[i] = dp[i - 1] + 1;
res = max(dp[i], res);
}
}
return res;
}
};
dp[i][j]:0-i的nums1与0-j的nums2的公共最长子数组的长度
因此当nums2[j] == nums1[j]时dp[i][j]等于dp[i - 1][j - 1] + 1;反之,dp[i][j]应该为0,因为子数组是连续的,nums2[j] != nums1[j]时意味着子数组在这里断掉了,要重新计数
dp[i][j]定义为:以下标i - 1为结尾的A,和以下标j - 1为结尾的B,最长重复子数组长度为dp[i][j]。那么可以避免写初始化
代码如下:
class Solution {
public:
int findLength(vector<int>& nums1, vector<int>& nums2) {
int n = nums1.size();
int m = nums2.size();
// dp[i][j]:0-i的nums1与0-j的nums2的公共最长子数组的长度
vector<vector<int>> dp(n, vector<int>(m, 0));
int res = 0;
for (int i = 0; i < n; ++i) {
if (nums1[i] == nums2[0]) {
dp[i][0] = 1;
res = 1;
}
}
for (int j = 1; j < m; j++) {
if (nums2[j] == nums1[0]) {
dp[0][j] = 1;
res = 1;
}
}
for (int i = 1; i < n; ++i) {
for (int j = 1; j < m; j++) {
if (nums1[i] == nums2[j]) {
dp[i][j] = dp[i - 1][j - 1] + 1;
res = max(res, dp[i][j]);
} else {
dp[i][j] = 0;
}
}
}
return res;
}
};
class Solution {
public:
int findLength(vector<int>& nums1, vector<int>& nums2) {
vector<vector<int>> dp (nums1.size() + 1, vector<int>(nums2.size() + 1, 0));
int result = 0;
for (int i = 1; i <= nums1.size(); i++) {
for (int j = 1; j <= nums2.size(); j++) {
if (nums1[i - 1] == nums2[j - 1]) {
dp[i][j] = dp[i - 1][j - 1] + 1;
}
if (dp[i][j] > result) result = dp[i][j];
}
}
return result;
}
};