LeetCode 39. 组合总和

题目描述

给你一个 无重复元素 的整数数组 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.选与不选

解题思路

题目中提到元素无限制重复被选取,同时又有选与不选的性质,设置两个终止条件,遍历过程中分成选与不选,当前元素如果是"选"",那么i不再加1,以此实现无限制重复被选取。

cpp 复制代码
class Solution {
public:
    vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
        vector <vector <int>> ans;
        vector <int> nums;
        auto dfs = [&](this auto && dfs,int i,int sum){
            if(sum == 0){
                ans.push_back(nums);
                return;
            }

            if(i == candidates.size() || sum < 0) return;
            //不选
            dfs(i + 1,sum);
            //选
            nums.push_back(candidates[i]);
            dfs(i,sum - candidates[i]);   //i不变,实现重复选择
            nums.pop_back(); //回溯
        };
        dfs(0,target);
        return ans; 
    }
};

2.选与不选(剪枝)

上面方法中,只有递归到最后才能终止,递归过程会浪费多余时间,如果candidates是递增的,我们就只需要判断当前的sum是否小于candidates当前元素就可以确定要不要继续遍历,实现剪枝,但是给数组排序会占用额外的时间。

cpp 复制代码
class Solution {
public:
    vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
        sort(candidates.begin(),candidates.end());
        vector <vector <int>> ans;
        vector <int> nums;
        auto dfs = [&](this auto && dfs,int i,int sum){
            if(sum == 0){
                ans.push_back(nums);
                return;
            }

            if(i == candidates.size() || sum < candidates[i]) return;
            dfs(i + 1,sum);
            nums.push_back(candidates[i]);
            dfs(i,sum - candidates[i]);
            nums.pop_back();
        };
        dfs(0,target);
        return ans; 
    }
};
相关推荐
学传打活5 天前
【边打字.边学昆仑正义文化】_进阶篇5 宇宙星系的运转(续3)
微信公众平台·1024程序员节·汉字·昆仑正义文化
学传打活10 天前
【边打字.边学昆仑正义文化】_进阶篇5 宇宙星系的运转(续1)
微信公众平台·1024程序员节·汉字·昆仑正义文化
fangzhanpeng16818 天前
快速掌握C#语言基础知识点(1.基础数据类型)
开发语言·c#·1024程序员节
无己心20 天前
面向多平台 AI 搜索引擎的适配层架构设计
前端·人工智能·搜索引擎·ai·1024程序员节
u0103055271 个月前
AI驱动的安卓UI自动生成功能实现
人工智能·1024程序员节
u0103055271 个月前
长株潭智能体赋能腾讯元器链接共享
1024程序员节
云贝贝贝1 个月前
OceanBase认证体系介绍与备考指南
运维·服务器·oceanbase·1024程序员节
u0103055271 个月前
Java图像处理实战指南
人工智能·1024程序员节
u0103055271 个月前
Java AWT鼠标事件全解析
人工智能·1024程序员节
u0103055271 个月前
Java实用类应用精讲
人工智能·1024程序员节