代码随想录算法训练营第四十天| 300.最长递增子序列 674. 最长连续递增序列 718. 最长重复子数组

300.最长递增子序列

要求:

可以删减任意个节点,最后保存最大的递增长度

难点:

4 10 4 8 9

如何 保证全局的视角,看到很前面的节点是否大于当前的节点,而不是仅仅记录状态

思路:

dp[n] , 当子序列的末尾为N时,它的最大子序列长度

也就意味着,N在它的子序列中是最大的,遍历这个N之前的所有序列,如果比他们大,就+1

注意, 2 1 3, 虽然3 比1 2都大,但是为2,

如何做到这一点?

dp[i] = max(dp[i], dp[j]+1),所以2 当时是1,1也是1,所以3是2,而不会是3

代码:

 1 // 要求:最长严格递增子序列长度 可以删除任意节点
 2 // 难点:如何全局的看到后面的情况0
 3 // 
 4 // dp[n] : 以nums[n]为结尾的最长递增子序列的长度!!! 很重要
 5 // 
 6 // dp[i] = 因为是以I为结尾,所以需要把I之前的所有节点都遍历一下,找到目前最长的子序列长度
 7 //
 8 int lengthOfLIS(vector<int>& nums) {
 9     if (nums.size() == 1) return 1;
10 
11     vector<int>dp(nums.size(), 1);
12 
13     for (int i = 1; i < nums.size(); i++)
14     {
15         // 从而实现了全局,也就是4 10 4 8 9 的问题, dp[i] = dp[i-1]+1 , dp[i-1]
16         for (int j = 0; j < i; j++)
17         {
18             if (nums[j] < nums[i])
19             {
20                 //很巧妙 一定要会用
21                 dp[i] = max(dp[i], dp[j] + 1);
22             }
23         }
24     }
25 
26     int result = INT_MIN;
27     for (int i = 0; i < dp.size(); i++)
28     {
29         result = result > dp[i] ? result : dp[i];
30     }
31 
32     return result;
33 }

 674. 最长连续递增序列

比较简单:

代码

 1 // 要求:这个必须是连续的递增子序列,不可以任意删减
 2 // 
 3 //
 4 int findLengthOfLCIS(vector<int>& nums) {
 5     if (nums.size() == 1) return 1;
 6 
 7     vector<int> dp(nums.size(), 1);
 8     int result = INT_MIN;
 9     for (int i = 1; i < nums.size(); i++)
10     {
11         if (nums[i] > nums[i - 1])
12         {
13             dp[i] = dp[i - 1] + 1;
14         }
15 
16         result = result > dp[i] ? result : dp[i];
17     }
18 
19     return result;
20 }

  718. 最长重复子数组 

要求:

有两个数组,求出来里面最长的重复子数组:也就是,最长的交集

思路:

dp[n][m] 第一个数组的第n-1 和 第二个数组的m-1中的重复的子数组

细节分析:

对于第N-1个nums1数组,他会和nums2数组的每个元素都进行比较,然后如果和 2 3,都相等,那么这两个都会+1

紧接着下一个nums1,会和nums2比较,如果相等,那么就会在前面的基础上累加

代码:

// 要求:字符串匹配,找出来最长的子字符串 KMP算法需要再复习
// 
// 最短的那个子数组为字符串匹配的来源
// 
// dp[n],第N个匹配的子序列长度,需要记录N 在1中匹配的index 列表
// 
// 难点:可能1 2 1 3 用1匹配,那么有两个节点
// 
// 新思路:dp[n][m] 在第n-1 m-1的子序列中重复数组的长度
// 
// nums1 = [1,2,3,2,1], nums2 = [3,2,1,4,7]
// 
// dp[i][j] = dp[i-1][j-1]+1
//
int findLength(vector<int>& nums1, vector<int>& nums2) {
    int result = 0;

    vector<vector<int>> dp(nums1.size() + 1, vector<int>(nums2.size() + 1, 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 = result > dp[i][j] ? result : dp[i][j];
            }
        }
    }

    return result;
}

 

posted @ 2023-07-28 10:27  博二爷  阅读(2)  评论(0编辑  收藏  举报