leetCode 2915. 和为目标值的最长子序列的长度 + 动态规划 +01背包 + 空间优化 + 记忆化搜索 + 递推

这篇具有很好参考价值的文章主要介绍了leetCode 2915. 和为目标值的最长子序列的长度 + 动态规划 +01背包 + 空间优化 + 记忆化搜索 + 递推。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

2915. 和为目标值的最长子序列的长度 - 力扣(LeetCode)


给你一个下标从 0 开始的整数数组 nums 和一个整数 target 。返回和为 target 的 nums 子序列中,子序列 长度的最大值 。如果不存在和为 target 的子序列,返回 -1 。子序列 指的是从原数组中删除一些或者不删除任何元素后,剩余元素保持原来的顺序构成的数组。

leetCode 2915. 和为目标值的最长子序列的长度 + 动态规划 +01背包 + 空间优化 + 记忆化搜索 + 递推,动态规划,leetcode,动态规划,01背包,记忆化搜索,空间优化,递推,回溯

(一)回溯 

  • f(i,j) 表示在物品集 nums 的前 i 选取物品,使得装满容量j 的背包有最多个物品
  • 也就是f(i,j) 表示在数组 nums 前 i 个的选取元素,使得这些元素之和等于 j 最长子序列长度
  • leetCode 2915. 和为目标值的最长子序列的长度 + 动态规划 +01背包 + 空间优化 + 记忆化搜索 + 递推,动态规划,leetcode,动态规划,01背包,记忆化搜索,空间优化,递推,回溯
class Solution {
public:
    // 递归搜索
    int lengthOfLongestSubsequence(vector<int>& nums, int target) {
        int n = nums.size();
        function<int(int,int)>dfs=[&](int i,int s) -> int {
            if(i<0) { 
                if(s==0) return 0;
                else return INT_MIN;
            }
            return max(dfs(i-1,s),dfs(i-1,s-nums[i])+1);
        };
        int ans = dfs(n-1,target);
        return ans<0?-1:ans;
    }
};

(二) 递归搜索 + 保存计算结果 = 记忆化搜索

class Solution {
public:
    // 记忆化递归搜索
    int lengthOfLongestSubsequence(vector<int>& nums, int target) {
        int n = nums.size();
        vector<vector<int>> memo(n,vector<int>(target+1,-1));
        function<int(int,int)>dfs=[&](int i,int s) -> int {
            if(i<0) { 
                if(s==0) return 0;
                else return INT_MIN;
            }
            int& res = memo[i][s];
            if(res != -1) return res;
            if (s < nums[i]) return res = dfs(i-1,s);
            return res = max(dfs(i-1,s),dfs(i-1,s-nums[i])+1);
        };
        int ans = dfs(n-1,target);
        return ans<0?-1:ans;
    }
};
class Solution {
public:
    // 记忆化递归搜索
    int lengthOfLongestSubsequence(vector<int>& nums, int target) {
        int n = nums.size();
        vector<vector<int>> memo(n+1,vector<int>(target+1,-1));
        function<int(int,int)>dfs=[&](int i,int s) -> int {
            if(i<0) { 
                if(s==0) return 0;
                else return INT_MIN;
            }
            int& res = memo[i+1][s];
            if(res != -1) return res;

            // 不选
            int& x = memo[i][s];
            if(x == -1) x=dfs(i-1,s);
            if (s < nums[i]) return res=x;

            // 选
            int& y = memo[i][s-nums[i]];
            if(y == -1) y=dfs(i-1,s-nums[i]);
            return res = max(x,y+1);
        };
        int ans = dfs(n-1,target);
        return ans<0?-1:ans;
    }
};

(三)1:1 翻译成递推

  • leetCode 2915. 和为目标值的最长子序列的长度 + 动态规划 +01背包 + 空间优化 + 记忆化搜索 + 递推,动态规划,leetcode,动态规划,01背包,记忆化搜索,空间优化,递推,回溯
  • leetCode 2915. 和为目标值的最长子序列的长度 + 动态规划 +01背包 + 空间优化 + 记忆化搜索 + 递推,动态规划,leetcode,动态规划,01背包,记忆化搜索,空间优化,递推,回溯
  • leetCode 2915. 和为目标值的最长子序列的长度 + 动态规划 +01背包 + 空间优化 + 记忆化搜索 + 递推,动态规划,leetcode,动态规划,01背包,记忆化搜索,空间优化,递推,回溯
class Solution {
public:
    // 递推
    int lengthOfLongestSubsequence(vector<int>& nums, int target) {
        int n = nums.size();
        vector<vector<int>> f(n+1,vector<int>(target+1,INT_MIN));
        f[0][0]=0;
        for(int i=0;i<nums.size();i++) {
            for(int j=0;j<=target;j++) {
                // if(j>=nums[i]) f[i+1][j] = max(f[i][j],f[i][j-nums[i]]+1);
                // else f[i+1][j] = f[i][j];
                f[i+1][j] = f[i][j];
                if(j>=nums[i]) f[i+1][j] = max(f[i][j],f[i][j-nums[i]]+1);
            }
        }
        int ans = f[n][target];
        return ans<0?-1:ans;
    }
};

进一步优化:

class Solution {
public: 
    // 递推 + 优化
    int lengthOfLongestSubsequence(vector<int>& nums, int target) {
        int n = nums.size();
        vector<vector<int>> f(n+1,vector<int>(target+1,INT_MIN));
        int sum=0;
        for(int i=0;i<nums.size();i++) {
            f[i][0]=0;
            sum=min(sum+nums[i],target);
            for(int j=1;j<=sum;j++) {
                f[i+1][j] = f[i][j];
                if(j>=nums[i]) f[i+1][j] = max(f[i][j],f[i][j-nums[i]]+1);
            }
        }
        int ans = f[n][target];
        return ans<0?-1:ans;
    }
};

>>空间优化

  • 1、二维数组空间优化
class Solution {
public:
    // 二维空间优化
    int lengthOfLongestSubsequence(vector<int>& nums, int target) {
        int n = nums.size();
        vector<vector<int>> dp(2,vector<int>(target+1,INT_MIN));
        int sum=0;
        for(int i=0;i<n;i++) {
            dp[i%2][0]=0;
            sum=min(sum+nums[i],target);
            for(int j=1;j<=sum;j++) {
                if(j >= nums[i]) dp[(i+1)%2][j] = max(dp[i%2][j],dp[i%2][j-nums[i]]+1);
                else dp[(i+1)%2][j] = dp[i%2][j];
            }
        }
        int ans = dp[n%2][target];
        return ans<0?-1:ans;
    }
};
  • 2.一维空间优化
class Solution {
public:
    // 一维空间优化
    int lengthOfLongestSubsequence(vector<int>& nums, int target) {
        int n = nums.size();
        vector<int> dp(target+1,INT_MIN);
        dp[0]=0;
        int sum=0;
        for(int i=0;i<n;i++) {
            sum=min(sum+nums[i],target);
            for(int j=sum;j>=nums[i];j--) {
                dp[j] = max(dp[j],dp[j-nums[i]]+1);
            }
        }
        int ans = dp[target];
        return ans<0?-1:ans;
    }
};

leetCode 2915. 和为目标值的最长子序列的长度 + 动态规划 +01背包 + 空间优化 + 记忆化搜索 + 递推,动态规划,leetcode,动态规划,01背包,记忆化搜索,空间优化,递推,回溯

leetCode 2915. 和为目标值的最长子序列的长度 + 动态规划 +01背包 + 空间优化 + 记忆化搜索 + 递推,动态规划,leetcode,动态规划,01背包,记忆化搜索,空间优化,递推,回溯

leetCode 2915. 和为目标值的最长子序列的长度 + 动态规划 +01背包 + 空间优化 + 记忆化搜索 + 递推,动态规划,leetcode,动态规划,01背包,记忆化搜索,空间优化,递推,回溯内容总结来自B站这位up主(Horn_JoJo)的视频简介:(总结得超棒!!!)

动态规划之选或者不选 通过「选」「不选」,确定子问题与原问题的联系。子问题又可以通过同样的「选」或者「不选」来再次找到子子问题与子问题的联系。这样就可以不断将问题拆成子问题。就构成了一个搜索树。当拆分到一定程度时,则找到了最容易解决的子问题。这样就可以先将子问题解决掉,然后反过来解决较大的子问题。这样就可以解决原问题了。

  • 树的根结点时原问题。树的叶子结点是边界或者最小子问题
  • 直接递归(满二叉树本,有重复子问题), 记忆化搜索(递归+记录)减少重复计算。
  • :省略递」的过程,直接「归」的过程中计算。

推荐和参考文章、视频: 

116双周赛T3复盘_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1Zg4y197BR/?spm_id_from=333.788.top_right_bar_window_history.content.click&vd_source=a934d7fc6f47698a29dac90a922ba5a3

动态规划入门:从记忆化搜索到递推_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1Xj411K7oF/?spm_id_from=333.788&vd_source=a934d7fc6f47698a29dac90a922ba5a3

2915. 和为目标值的最长子序列的长度 - 力扣(LeetCode)https://leetcode.cn/problems/length-of-the-longest-subsequence-that-sums-to-target/solutions/2502839/mo-ban-qia-hao-zhuang-man-xing-0-1-bei-b-0nca/我的往期文章:

leetCode 198.打家劫舍 动态规划入门:从记忆化搜索到递推-CSDN博客https://blog.csdn.net/weixin_41987016/article/details/134179583?spm=1001.2014.3001.5501文章来源地址https://www.toymoban.com/news/detail-741561.html

到了这里,关于leetCode 2915. 和为目标值的最长子序列的长度 + 动态规划 +01背包 + 空间优化 + 记忆化搜索 + 递推的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • [双指针] (三) LeetCode LCR 179. 查找总价格为目标值的两个商品 和 15. 三数之和

    [双指针] (三) LeetCode LCR 179. 查找总价格为目标值的两个商品 和 15. 三数之和 查找总价格为目标值的两个商品 LCR 179. 查找总价格为目标值的两个商品 题目分析 (1) 数组内数字是升序 (2) 目标值为target (3) 找两数之和为target 解题思路 找两个数字的和与目标值相等,我们可以想到

    2024年02月05日
    浏览(45)
  • 【VUE】数字动态变化到目标值-vue-count-to

    vue-count-to是一个Vue组件,用于实现数字动画效果。它可以用于显示从一个数字到另一个数字的过渡动画。  插件名:vue-count-to 官方仓库地址:GitHub - PanJiaChen/vue-countTo: It\\\'s a vue component that will count to a target number at a specified duration https://panjiachen.github.io/countTo/demo/ 官方Demo地址:

    2024年02月11日
    浏览(38)
  • 算法27:最长回文子序列长度——范围模型

    目录 题目: 样本模型: 递归版本的范围模型 分析过程 动态规划版本 优化动态规划: 给定一个字符串str,返回这个字符串的最长回文子序列长度 比如 str = “a12b3c43def2ghi1kpm” * 最长回文子序列是“1234321”或者“123c321”,返回长度7 这一题使用样本模型,也可以解决,只需

    2024年02月07日
    浏览(30)
  • leetcode分类刷题:易混题辨析一、209. 长度最小的子数组 vs 560. 和为K的子数组

    1、刷题慢慢积累起来以后,遇到相似的题目时,会出现算法思路混淆了 2、这两道题都是对 连续子数组加和 进行考察,细节区别在于数组元素在209. 长度最小的子数组为 正整数(窗口增加元素递增,减少元素递减) ,在560. 和为K的子数组为 整数 3、209. 长度最小的子数组采

    2024年02月10日
    浏览(39)
  • 【python】求最长连续公共子序列长度的几种解法

      给定两个序列X和Y,返回最长连续的公共子序列长度。如果没有连续公共子序列,返回0. X和Y的元素都是整数。 示例: 输入: 1 5 7 3 4 5 7 3 4 4 5 7 -2 输出: 3  说明: 最长的连续公共子序列是[7,3,4] (X[2:4] 和Y[0:2]) 这道题在【leetcode1143】的基础上增加了公共子序列连续的限制。

    2024年02月10日
    浏览(45)
  • 【LeetCode动态规划#14】子序列系列题(最长递增子序列、最长连续递增序列、最长重复子数组、最长公共子序列)

    力扣题目链接(opens new window) 给你一个整数数组 nums ,找到其中最长严格递增子序列的长度。 子序列是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如,[3,6,2,7] 是数组 [0,3,1,6,2,2,7] 的子序列。 示例 1: 输入:nums = [10,9,2,5,3,7,101,18] 输出

    2024年02月01日
    浏览(55)
  • Leetcode:300. 最长递增子序列、674. 最长连续递增序列(C++)

    目录 300. 最长递增子序列 题目描述: 实现代码: 原理思路: 674. 最长连续递增序列 题目描述: 实现代码: 原理思路: 题目描述:         给你一个整数数组  nums  ,找到其中最长严格递增子序列的长度。 子序列  是由数组派生而来的序列,删除(或不删除)数组中

    2024年02月11日
    浏览(54)
  • LeetCode | C++ 动态规划——300.最长递增子序列、674. 最长连续递增序列、718. 最长重复子数组

    300题目链接 dp 数组定义 dp[i] 表示 i 之前包括 i 的以 nums[i]结尾 的最长递增子序列的长度 需要包含nums[i]结尾,不然在做递增比较的时候,就没有意义了。 递推公式 位置 i 的最长递增子序列 等于 j 从 0 到 i - 1各个位置的最长递增子序列 + 1 的 最大值 if (nums[i] nums[j]) dp[i] = ma

    2024年02月16日
    浏览(45)
  • LeetCode128.最长连续序列

     我这个方法有点投机取巧了,题目说时间复杂度最多O(n),而我调用了Arrays.sort()方法,他的时间复杂度是n*log(n),但是AC了,这样的话这道题还是非常简单的,创建一个Hashmap,以nums数组的元素作为key,以这个元素是连续序列中的第几个作为value,先把数组排一下序,然后从第

    2024年02月12日
    浏览(29)
  • 【Leetcode】128.最长连续序列

    给定一个未排序的整数数组 nums ,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。 请你设计并实现时间复杂度为 O(n) 的算法解决此问题。 示例1: 示例2: 提示 : 0 = nums.length = 10 5 -10 9 = nums[i] = 10 9

    2024年02月10日
    浏览(62)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包