【300.最长递增子序列】
这个 题目里面dp数组的定义比较好理解。就是第i个元素有多少个最长递增子序列。
比较难理解的是dp数组的递推公式。
原理是,将i之前的元素逐个和nums[i]进行比较,如果nums[i]大于nums[j]那么就意味着可以更新dp[i]的值,更新dp[i]的条件是dp[j]+1大于dp[i]。
下面我们可以写出代码:
class Solution {
public:
int lengthOfLIS(vector<int>& nums) {
if(nums.size() <= 1)return nums.size();
int res = 0;
vector<int>dp(nums.size(), 1);
for(int i = 1; i < nums.size(); i++){
for(int j = 0; j < i; j++){
if(nums[i] > nums[j])dp[i] = max(dp[i],dp[j]+1);
}
if(dp[i] > res)res = dp[i];
}
return res;
}
};
注意:结果是取所有dp[i]中最大的值,所以res要每次遍历之后都更新。
【674. 最长连续递增序列】
这个题目比上个题目要简单点。简单的地方在于递推公式。
if(nums[i] > nums[i-1])dp[i] =dp[i-1]+1;
需要注意的是dp数组的定义是:以下标i为结尾的数组的连续最大的递增序列。
每次都需要更新一次resul
代码如下:
class Solution {
public:
int findLengthOfLCIS(vector<int>& nums) {
if(nums.size() == 0)return 0;
int res = 1;
vector<int>dp(nums.size(), 1);
for(int i = 1; i < nums.size(); i++){
if(nums[i] > nums[i-1])dp[i] = dp[i-1]+1;
if(dp[i] > res)res = dp[i];
}
return res;
}
};
【718. 最长重复子数组】
这个题目重点在于弄清楚dp数组的定义:
dp[i][j]为以下标i-1为结束的子数组和以j-1为结束的子数组的最长重复子数组的长度。
有了这个定义之后,我们的递推公式就简单了。如果nums [i-1] ==nums[j-1]那么dp[i][j]=dp[i-1][j-1]+1
代码如下:
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;
}
};