动态规划
300. 最长递增子序列
题意:给你一个整数数组 nums ,找到其中最长严格递增子序列的长度。子序列 是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如,[3,6,2,7] 是数组 [0,3,1,6,2,2,7] 的子序列。
实例:
思路:本题的思路主要是使用两层for循环遍历,第一层用于遍历整个数组找出最大递增子序列,第二层for主要是确定i号位置的包括之前的元素中的最长长度是多少。最终我们定义的数组中会存储最长递增子序列的长度,但是并不一定在最后,因此还需要排序进行判断。
C++代码:
int lengthOfLIS(vector<int>& nums) {
vector<int> dp(nums.size(), 1);
for (int i = 1; i<nums.size(); i++)
{
for (int j = i; j >= 0; j--)
{
if (nums[i]>nums[j])
{
dp[i] = max(dp[i], dp[j] + 1);
}
}
}
sort(dp.begin(), dp.end());
return dp[nums.size() - 1];
}
674. 最长连续递增序列
题意:给定一个未经排序的整数数组,找到最长且 连续递增的子序列,并返回该序列的长度。
连续递增的子序列 可以由两个下标 l 和 r(l < r)确定,如果对于每个 l <= i < r,都有 nums[i] < nums[i + 1] ,那么子序列 [nums[l], nums[l + 1], ..., nums[r - 1], nums[r]] 就是连续递增子序列。
实例:
思路:本题就是前一个题的简单版本,只需要找出连续的递增子序列即可,不是连续的就不需要进行组合了,代码也比较简单,如下所示
C++代码:
int findLengthOfLCIS(vector<int>& nums) {
vector<int> dp(nums.size(),1);
for(int i=1;i<nums.size();i++)
{
if(nums[i-1]<nums[i])
{
dp[i]=dp[i-1]+1;
}
}
sort(dp.begin(),dp.end());
return dp[nums.size()-1];
}
718. 最长重复子数组
题意:给两个整数数组 nums1 和 nums2 两个数组中 公共的 、长度最长的子数组的长度 。
实例:
思路:本题的思路呢也是比较简单,和上一题类似,只需要找出连续的最长相同元素即可,不需要拼接。我们需要创建二维数组,当两元素相等,那么ij位置的长度就是dp[i][j]=dp[i-1][j-1]+1;不相等,那长度直接归0。
最后就是最长的相等子序列会在二维数组中,因此我们在遍历数组时,需要保存最长的长度。
C++代码:
int findLength(vector<int>& nums1, vector<int>& nums2) {
vector<vector<int>> dp(nums1.size()+1,vector<int>(nums2.size()+1,0));
int count=INT_MIN;
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;
}
count=max(count,dp[i][j]);
}
}
return count;
}