• 【动态规划——子序列】


    题目:300. 最长递增子序列

    链接: leetcode题目链接

    给你一个整数数组 nums ,找到其中最长严格递增子序列的长度。
    子序列 是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如,[3,6,2,7] 是数组 [0,3,1,6,2,2,7] 的子序列。

    示例 1:
    输入:nums = [10,9,2,5,3,7,101,18]
    输出:4
    解释:最长递增子序列是 [2,3,7,101],因此长度为 4 。

    示例 2:
    输入:nums = [0,1,0,3,2,3]
    输出:4

    示例3:
    输入:nums = [7,7,7,7,7,7,7]
    输出:1

    提示:
    1).1 <= nums.length <= 2500
    2).-10^4 <= nums[i] <= 10^4

    实现算法:动规

    dp[i]表示i之前包括i的以nums[i]结尾的最长递增子序列的长度

    class Solution {
    public:
        int lengthOfLIS(vector<int>& nums) {
            if (nums.size() <= 1) return nums.size();
            vector<int> dp(nums.size(), 1);
            int result = 0;
            for (int i = 1; i < nums.size(); i++) {
                for (int j = 0; j < i; j++) {
                    if (nums[i] > nums[j]) dp[i] = max(dp[i], dp[j] + 1);
                }
                if (dp[i] > result) result = dp[i]; // 取长的子序列
            }
            return result;
        }
    }; 
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    p.s.

    自我实现

    class Solution {
    public:
        int lengthOfLIS(vector<int>& nums) {
            vector<int> dp(nums.size(),1);
            int body=1;
            for(int i=1;i<nums.size();i++){
                for(int j=0;j<i;j++){
                    if(nums[i]>nums[j]) dp[i]=max(dp[j]+1,dp[i]);
                }
                if(dp[i]>body) body=dp[i];
            }
            return body;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    p.s.

    题目:674. 最长连续递增序列

    链接: leetcode题目链接

    给定一个未经排序的整数数组,找到最长且 连续递增的子序列,并返回该序列的长度。
    连续递增的子序列 可以由两个下标 l 和 r(l < r)确定,如果对于每个 l <= i < r,都有 nums[i] < nums[i + 1] ,那么子序列 [nums[l], nums[l + 1], …, nums[r - 1], nums[r]] 就是连续递增子序列。

    示例 1:
    输入:nums = [1,3,5,4,7]
    输出:3
    解释:最长连续递增序列是 [1,3,5], 长度为3。
    尽管 [1,3,5,7] 也是升序的子序列, 但它不是连续的,因为 5 和 7 在原数组里被 4 隔开。

    示例 2:
    输入:nums = [2,2,2,2,2]
    输出:1
    解释:最长连续递增序列是 [2], 长度为1。

    提示:
    1).1 <= nums.length <= 104
    2).-109 <= nums[i] <= 109

    实现算法:

    dp[i]:以下标i为结尾的连续递增的子序列长度为dp[i]。

    方法思路:

    class Solution {
    public:
        int findLengthOfLCIS(vector<int>& nums) {
            if (nums.size() == 0) return 0;
            int result = 1;
            vector<int> dp(nums.size() ,1);
            for (int i = 1; i < nums.size(); i++) {
                if (nums[i] > nums[i - 1]) { // 连续记录
                    dp[i] = dp[i - 1] + 1;
                }
                if (dp[i] > result) result = dp[i];
            }
            return result;
        }
    };
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    p.s.

    自我实现

    class Solution {
    public:
        int findLengthOfLCIS(vector<int>& nums) {
            vector<int> dp(nums.size(),1);
            int count=1;
            for(int i=1;i<nums.size();i++){
                if(nums[i]>nums[i-1]) dp[i]=dp[i-1]+1;
                if(count<dp[i]) count=dp[i];
            }
            return count;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    p.s.

    题目:718. 最长重复子数组

    链接: leetcode题目链接

    给两个整数数组 nums1 和 nums2 ,返回 两个数组中 公共的 、长度最长的子数组的长度 。

    示例 1:
    输入:nums1 = [1,2,3,2,1], nums2 = [3,2,1,4,7]
    输出:3
    解释:长度最长的公共子数组是 [3,2,1] 。

    示例 2:
    输入:nums1 = [0,0,0,0,0], nums2 = [0,0,0,0,0]
    输出:5

    提示:
    1).1 <= nums1.length, nums2.length <= 1000
    2).0 <= nums1[i], nums2[i] <= 100

    实现算法:

    dp[i][j] :以下标i - 1为结尾的A,和以下标j - 1为结尾的B,最长重复子数组长度为dp[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;
                    }
                    if (dp[i][j] > result) result = dp[i][j];
                }
            }
            return result;
        }
    };
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    p.s.
    两个数组比较,一般都设为以下标i - 1为结尾的A,和以下标j - 1为结尾的B,方便初始化

    自我实现

    class Solution {
    public:
        int findLength(vector<int>& nums1, vector<int>& nums2) {
            int count=0;
            vector<vector<int>> dp(nums1.size(),vector<int>(nums2.size(),0));
            for(int i=0;i<nums1.size();i++){
                if(nums1[i]==nums2[0]) dp[i][0]=1;
                if(dp[i][0]>count) count=dp[i][0];
            }
            for(int j=0;j<nums2.size();j++){
                if(nums2[j]==nums1[0]) dp[0][j]=1;
                if(dp[0][j]>count) count=dp[0][j];
            }
            
            for(int i=1;i<nums1.size();i++){
                for(int j=1;j<nums2.size();j++){
                    if(nums1[i]==nums2[j]) dp[i][j]=dp[i-1][j-1]+1;
                    //else dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
                    if(dp[i][j]>count) count=dp[i][j];
                }
                
            }
            return count;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    p.s.

    题目:1143. 最长公共子序列

    链接: leetcode题目链接

    给定两个字符串 text1 和 text2,返回这两个字符串的最长 公共子序列 的长度。如果不存在 公共子序列 ,返回 0 。
    一个字符串的 子序列 是指这样一个新的字符串:它是由原字符串在不改变字符的相对顺序的情况下删除某些字符(也可以不删除任何字符)后组成的新字符串。
    例如,“ace” 是 “abcde” 的子序列,但 “aec” 不是 “abcde” 的子序列。
    两个字符串的 公共子序列 是这两个字符串所共同拥有的子序列。

    示例 1:
    输入:text1 = “abcde”, text2 = “ace”
    输出:3
    解释:最长公共子序列是 “ace” ,它的长度为 3 。

    示例 2:
    输入:text1 = “abc”, text2 = “abc”
    输出:3
    解释:最长公共子序列是 “abc” ,它的长度为 3 。

    示例3:
    输入:text1 = “abc”, text2 = “def”
    输出:0
    解释:两个字符串没有公共子序列,返回 0 。

    提示:
    1).1 <= text1.length, text2.length <= 1000
    2).text1 和 text2 仅由小写英文字符组成。

    实现算法:

    dp[i][j]:长度为[0, i - 1]的字符串text1与长度为[0, j - 1]的字符串text2的最长公共子序列为dp[i][j]

    
    class Solution {
    public:
        int longestCommonSubsequence(string text1, string text2) {
            vector<vector<int>> dp(text1.size() + 1, vector<int>(text2.size() + 1, 0));
            for (int i = 1; i <= text1.size(); i++) {
                for (int j = 1; j <= text2.size(); j++) {
                    if (text1[i - 1] == text2[j - 1]) {
                        dp[i][j] = dp[i - 1][j - 1] + 1;
                    } else {
                        dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
                    }
                }
            }
            return dp[text1.size()][text2.size()];
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    p.s.

    自我实现

    
    
    • 1

    p.s.

    做题心得

    做题心得

  • 相关阅读:
    MapReduce、hive、hadoop的一些笔记
    YOLOv8中训练参数中文解释
    Qt报错总结
    axios 请求的缓存封装
    js内存与数据
    解决xinput1_3.dll丢失的终极方法!快来尝试这4个方法吧!
    threejs球体旋转与场景旋转_js 之threejs地球旋转
    CloudCompare&PCL ICP配准(点到面)
    B站数据,怎样查看B站带货商品数据?
    【web开发】spring security配合验证码,java获取地理位置(绘制百度地图)、天气
  • 原文地址:https://blog.csdn.net/m0_57487222/article/details/133500679