300.最长递增子序列
思路:
- 1.dp存储:以nums[i]为结尾的最长递增子序列的长度为 dp[i]
- 2.动态转移方程:dp[i]=max(dp[j]+1,dp[i])
- 3.初始值都为1 (因为每一个开始都是1)
- 4.遍历顺序:i:1-n j:0-i
class Solution {
public:
int lengthOfLIS(vector<int>& nums) {
int n=nums.size();
int res=1;
vector<int>dp(n,1);
for(int i=1;i<n;i++){
for(int j=0;j<i;j++){
if(nums[i]>nums[j]) //当递增的时候
dp[i]=max(dp[j]+1,dp[i]);
}
if(dp[i]>res) res=dp[i];//更新最长递增子序列
}
return res;
}
};
674.最长连续递增序列
思路一:双指针(连续长度+1,不连续左边界更新为右边界)
class Solution {
public:
int findLengthOfLCIS(vector<int>& nums) {
int res=1,left=0,right=0;
int n=nums.size();
for(int i=1;i<n;i++){
if(nums[i]>nums[i-1]) right++;
else{
res=max(res,right-left+1);
left=right;
}
}
res=max(res,right-left+1);
return res;
}
};
思路二:动态规划
- 1.dp存储:以nums[i]结尾的序列中,最长递增连续子序列为dp[i]
- 2.动态转移方程 :dp[i]=dp[i-1]+1;
- 3.初始化:全为1
- 4.遍历顺序:i:1-n
class Solution {
public:
int findLengthOfLCIS(vector<int>& nums) {
int res=1,left=0,right=0;
int n=nums.size();
vector<int>dp(n,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;
}
};
718.最长重复数组
思路:
- 1.dp存储:以i-1为结尾的nums1,和以j-1为结尾的nums2,最长重复子数组的长度为dp[i][i]
- 2.动态转移方程:dp[i][j]=dp[i-1][j-1]+1
- 3.初始化:全部为0
- 4.遍历顺序:1-n
class Solution {
public:
int findLength(vector<int>& nums1, vector<int>& nums2) {
int n=nums1.size(),m=nums2.size();
int res=0;
vector<vector<int>>dp(n+1,vector<int>(m+1,0));
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){//nums1中的每一个元素都会对nums2中的每一个元素进行遍历
//每一个dp[i][j]都存储了重复状态
if(nums1[i-1]==nums2[j-1]) dp[i][j]=dp[i-1][j-1]+1;
if(dp[i][j]>res) res=dp[i][j];
}
}
return res;
}
};