LeetCode 300 最长递增子序列
题目链接:https://leetcode.cn/problems/longest-increasing-subsequence/
思路:
dp数组的含义
dp[i]代表以nums[i]结尾的最长递增子序列的长度
递推公式
![](https://img-blog.csdnimg.cn/img_convert/a0c1dde9fbe7009013dddb77d276cc85.png)
如果nums[i]>nums[j],显然此时,。考虑到求的是最大值,所以整体递推公式为:
初始化
每一个数字都代表自身是一个递增子序列,所以:
遍历顺序
对于i的遍历顺序,显然是从前往后,一直到nums.size()-1为止;对于j的遍历顺序,从前往后还是从后往前都可以,只要遍历完0~i-1的元素即可。
代码:
class Solution {
public:
int lengthOfLIS(vector<int>& nums) {
vector<int>dp(nums.size(), 1);
int result = 1;
for(int i = 1; i < nums.size(); i++)
{
for(int j = 0; j < i; j++)
{
if(nums[j] < nums[i])
{
dp[i] = max(dp[i], dp[j] + 1);
}
}
result = max(result, dp[i]);
}
return result;
}
};
总结
第一次写子序列问题,在dp数组的定义上出现了差错
LeetCode 674 最长连续递增序列
题目链接:https://leetcode.cn/problems/longest-continuous-increasing-subsequence/
思路:
dp数组的含义
dp[i]代表以nums[i]结尾的最长连续递增子序列的长度
递推公式
如果nums[i]>nums[i - 1],显然此时,。考虑到求的是最大值,所以整体递推公式为:
if(nums[i] > nums[i - 1])
dp[i] = dp[i - 1] + 1;
初始化
每一个数字都代表自身是一个递增子序列,所以:
遍历顺序
对于i的遍历顺序,显然是从前往后。
代码:
class Solution {
public:
int findLengthOfLCIS(vector<int>& nums) {
vector<int>dp(nums.size(), 1);
int result = 1;
for(int i = 1; i < nums.size(); i++)
{
if(nums[i] > nums[i - 1])
dp[i] = dp[i - 1] + 1;
result = max(result, dp[i]);
}
return result;
}
};
总结
比前一道题简单很多,因为要求是连续的递增序列
LeetCode 718 最长重复子数组
题目链接:https://leetcode.cn/problems/maximum-length-of-repeated-subarray/
思路:
dp数组的含义
dp[i][j]代表以i-1结尾的nums1数组和以j-1结尾的nums2数组最长的重复子数组大小
递推公式
因为dp数组是i-1和j-1,所以相等的条件是:nums1[i-1]==nums[j-1]
所以递推公式:
if(nums1[i - 1] == nums2[j - 1])
dp[i][j] = dp[i - 1][j - 1] + 1;
初始化
dp[i][0]和dp[0][j]显然都是没有意义的,即二维数组的第一行和第一列,将其全部初始化为0即可。其余数值因为会在递推公式中被覆盖,所以也都初始化为0,这样可以使得代码相对简洁。
遍历顺序
i和j的遍历,然是从前往后,直到二者相等
代码:
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;
result = max(result, dp[i][j]);
}
}
return result;
}
};
总结
dp数组的含义要牢记,在子序列的距离问题中,dp[i][j]代表的是以i-1和j-1结尾的。
今日总结:
开始子序列动态规划问题的学习。