300. 最长递增子序列
cpp
class Solution {
public:
int lengthOfLIS(vector<int>& nums) {
int n=nums.size();
int max_len=1;
vector<int> dp(n,1);
for(int i=1; i<n; i++){
for(int j=0; j<i; j++){
if(nums[j]<nums[i])
dp[i]=max(dp[i],dp[j]+1);
}
max_len=max(max_len,dp[i]);
}
return max_len;
}
};
dp[i]:以下标i为终点的递增子序列的最大长度
转移方程:可由前置的任何一个j转移而来(满足递增的情况下),累计最大得到dp[i],对所有dp取最大值得到全局最大,注意最长递增子序列不一定要取到末尾元素,可能在中间最大。
674. 最长连续递增序列
cpp
class Solution {
public:
int findLengthOfLCIS(vector<int>& nums) {
int n = nums.size();
int max_len=1;
vector<int> dp(n, 1);
for (int i = 1; i < n; i++) {
if (nums[i - 1] < nums[i])
dp[i] = dp[i - 1] + 1;
max_len=max(max_len,dp[i]);
}
return max_len;
}
};
和上题的差异在"连续",意味着只能从上一个元素(i-1)转移而来,而不用遍历所有前置节点。
718. 最长重复子数组
cpp
class Solution {
public:
int findLength(vector<int>& nums1, vector<int>& nums2) {
nums1.insert(nums1.begin(),-1);
nums2.insert(nums2.begin(),-1);
int n1=nums1.size(), n2=nums2.size(), max_len=0;
vector<vector<int>> dp(n1,vector<int>(n2,0));
for(int i=1; i<n1; i++){
for(int j=1; j<n2; j++){
if(nums1[i]==nums2[j]){
dp[i][j]=dp[i-1][j-1]+1;
}
max_len=max(max_len,dp[i][j]);
}
}
return max_len;
}
};
两个输入,二维dp,定义dp[i][j]:使用nums1[i]及nums2[j]结尾的重复子数组的最大长度
转移方程:
1.如果结尾元素相等,则可由删除结尾的子串的最长重复子数组转移而来
2.如果结尾元素不等,则一定为0