• 经典动态规划问题的递归实现方法——LeetCode39 组合总和


    题目内容

    给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ,找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 ,并以列表形式返回。你可以按 任意顺序 返回这些组合。

    candidates 中的 同一个 数字可以 无限制重复被选取 。如果至少一个数字的被选数量不同,则两种组合是不同的。

    对于给定的输入,保证和为 target 的不同组合数少于 150 个。

    示例 1:

    输入:candidates = [2,3,6,7], target = 7
    输出:[[2,2,3],[7]]
    解释:
    2 和 3 可以形成一组候选,2 + 2 + 3 = 7 。注意 2 可以使用多次。
    7 也是一个候选, 7 = 7 。
    仅有这两种组合。

    示例 2:

    输入: candidates = [2,3,5], target = 8
    输出: [[2,2,2,2],[2,3,3],[3,5]]

    示例 3:

    输入: candidates = [2], target = 1
    输出: []

    提示:

    1 <= candidates.length <= 30
    1 <= candidates[i] <= 200
    candidate 中的每个元素都 互不相同
    1 <= target <= 500

    来源:力扣(LeetCode) 链接:https://leetcode.cn/problems/combination-sum
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

    解题思路

    在这里插入图片描述

    首先,这个明显不是双指针类型的问题了,像与这个题目题意类似的有三个数求和=target或者四个数求和,那些题目用双指针可以优化函数,不过这里肯定是不能这样用的了,原理显而易见:我们不知道循环的次数。而对于这种不知道循环次数的题目,那不就是标准的DFS发挥的空间了吗?

    其实这道题本质上和动态规划中特别有名的一类问题,就是有一定面额的钞票,然后问能不能拼出指定的金额非常类似。而且target本身也不大,所以用一个二维数组来做这个绝对是可行的。

    不过动态规划归根到底,不也是递归吗,就是递归经过记忆化和严格表化之后的结果。我们这里图一个方便,就直接递归解决了。

    这里主要遇到的一个问题在于选择数组的保存,这里我们需要注意使用一下回溯算法,因为choice虽然是参数,不过他是不会随着递归的系统栈腾出好几份的。所以记得在结束只后要pop回来,不过可以放心,这里和你push进去的绝对是同一个。

    最后还有一个小点,就是我们在遍历的时候,一定要确保不吃回头草,也就是脚标也要做一个参数,防止出现232,223,322这样排序不同但是实际意义一样的情况。毕竟在这里进行判断,一来麻烦,二来浪费。

    代码

    class Solution {
    public:
        vector<vector<int>> ans;
        void make(vector<int>& candidates, int target,vector<int> &choice,int biao){
            if(target==0){
                ans.push_back(choice);
                return;
            }
            if(target<0){
                return;
            }
            for(int i=biao;i<candidates.size();i++){
                choice.push_back(candidates[i]);
                make(candidates,target-candidates[i],choice,i);
                choice.pop_back();
            }
        }
    
        vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
            vector<int> choice;
            make(candidates,target,choice,0);
            return ans;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
  • 相关阅读:
    Maven上传本地离线依赖
    健康之路押注医药零售:毛利率下滑亏损扩大,医疗咨询人次大幅减少
    【场景化解决方案】项目管理结合酷应用,让企业项目管理更便捷高效
    检测到目标URL存在http host头攻击漏洞
    【JAVA程序设计】(C00088)基于SSM的病例管理系统
    防火墙软件 iptables
    Mac M芯片上安装统信UOS 1070arm64虚拟机
    Python | 快速获取某一列数组中前 N 个最大值/最小值的索引 | 三种方法总结
    iOS消息转发流程
    软考高级之系统架构师之数据流图和流程图
  • 原文地址:https://blog.csdn.net/weixin_51529433/article/details/126105652