LeetCode 刷题记录 39. Combination Sum

题目:
Given a set of candidate numbers (candidates) (without duplicates) and a target number (target), find all unique combinations in candidates where the candidate numbers sums to target.

The same repeated number may be chosen from candidates unlimited number of times.

Note:

All numbers (including target) will be positive integers.
The solution set must not contain duplicate combinations.
Example 1:

Input: candidates = [2,3,6,7], target = 7,
A solution set is:
[
[7],
[2,2,3]
]
Example 2:

Input: candidates = [2,3,5], target = 8,
A solution set is:
[
[2,2,2,2],
[2,3,3],
[3,5]
]
解法1:
递归法 用dfs
dfs函数有5个参数,candidates,其中一个解 vector& path,最终结果vector<vector>& res,现在与target的差值gap,这意味着
递归采用的起点是target,终点是 gap <=0,采用减法操作,这里不采用加法操作的原因是如果用加法递归采用的起点是0,终点是 gap>= target,在递归函数中我们还要多传一个参数target,start当前递归的坐标,参数最好加入引用
递归基:如果gap<0,直接返回
gap=0,我们找到一个解,将解path加入到 res并返回
i 从start到candidates.size() - 1,依次尝试candidates中的数,首先path先加入这个数,继续递归,gap变为 gap - candidates[i],start还是i,因为本题中的数可以重复,递归成功后我们需要弹出我们之前加的数

例:[2,3,6,7] 11
在这里插入图片描述
在这里插入图片描述

c++:

class Solution {
public:
    vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
        vector<vector<int>> res;
        vector<int> path;
        DFS(candidates, path, res, target, 0);
        return res;
    }
    void DFS(vector<int>& candidates, vector<int>& path,vector<vector<int>>& res,int gap,int start){
        if(gap < 0) return;
        if(gap == 0){
            res.push_back(path);
            return;
        }
        for(int i = start; i < candidates.size(); ++i){
            path.push_back(candidates[i]);
            DFS(candidates, path, res, gap - candidates[i], i);
            path.pop_back();
        }
        
    }
    
};

java:

  1. java中函数参数要写List path,List<List> res,并且在添加结果时res.add(new ArrayList<>(path))而不是res.add(path)
    因为new ArrayList<>(path)是一个对象,是对path的拷贝,而path是List,只是这个对象的引用,这个对象的内容每次都会改变
  2. remove操作我们要取出末尾元素
class Solution {
    public List<List<Integer>> combinationSum(int[] candidates, int target) {
        List<List<Integer>>  res = new ArrayList<>();
        List<Integer> path = new ArrayList<>();
        //sort(candidates.begin(),candidates.end());
        //DFS(candidates, new ArrayList<>(), res, target, 0);
        DFS(candidates, path, res, target, 0);
        return res;
    }
    private void DFS(int[] candidates,List<Integer> path,List<List<Integer>> res,int gap,int start){
        
        if(gap < 0) return;
        if(gap == 0){
            res.add(new ArrayList<>(path));
            return;
        }
        for(int i = start; i < candidates.length; ++i){
//            cout << candidates[i] << endl;
           // if(gap < candidates[i]) return;
            path.add(candidates[i]);
            DFS(candidates, path, res, gap - candidates[i], i);
            path.remove(path.size() - 1);
        }
        
    }
}

python:

  1. python 不能用append和pop,因为python是引用传递,所以最后会得到空, 而path + [candidates[i]] 会形成一个新的列表
  2. path + [candidates[i]] 相当于append操作,当函数返回,函数参数仍为path,即完成pop操作
class Solution(object):
    def combinationSum(self, candidates, target):
        """
        :type candidates: List[int]
        :type target: int
        :rtype: List[List[int]]
        """
        res = []
        self.DFS(candidates, [], res, target, 0)
        return res
    def DFS(self, candidates, path, res,gap,start):
        if gap < 0: return
        if gap == 0:
            res.append(path)
            return
        for i in xrange(start, len(candidates)):
            #path.append(candidates[i])
            self.DFS(candidates, path + [candidates[i]], res, gap - candidates[i], i)
            #path.pop()
        
    

解法2:
递归法:剪枝
画圈的部分的递归是完全不需要的,如path(8) gap 3,我们在加入8时,只需做一个判断,gap < 8,说明这是我们不需要的,立即返回就可以了,但是我们要保证我们剪枝是正确的,即加入8不行,后面的就更加不行,这就要求我们先对数组进行排序
在这里插入图片描述
c++:

class Solution {
public:
    vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
        vector<vector<int>> res;
        vector<int> path;
        sort(candidates.begin(),candidates.end());
        DFS(candidates, path, res, target, 0);
        return res;
    }
    void DFS(vector<int>& candidates, vector<int>& path,vector<vector<int>>& res,int gap,int start){
        //if(gap < 0) return;
        if(gap == 0){
            res.push_back(path);
            return;
        }
        for(int i = start; i < candidates.size(); ++i){
//            cout << candidates[i] << endl;
            if(gap < candidates[i]) return;
            path.push_back(candidates[i]);
            DFS(candidates, path, res, gap - candidates[i], i);
            path.pop_back();
        }
        
    }
    
};

java:

class Solution {
    public List<List<Integer>> combinationSum(int[] candidates, int target) {
        List<List<Integer>>  res = new ArrayList<>();
        //List<Integer> path = new ArrayList<>();
        //sort(candidates.begin(),candidates.end());
        Arrays.sort(candidates);
        DFS(candidates, new ArrayList<>(), res, target, 0);
        return res;
    }
    private void DFS(int[] candidates,List<Integer> path,List<List<Integer>> res,int gap,int start){
        
        //if(gap < 0) return;
        if(gap == 0){
            res.add(new ArrayList<>(path));
            return;
        }
        for(int i = start; i < candidates.length; ++i){
//            cout << candidates[i] << endl;
            if(gap < candidates[i]) return;
            path.add(candidates[i]);
            DFS(candidates, path, res, gap - candidates[i], i);
            path.remove(path.size() - 1);
        }
        
    }
}

python:

class Solution(object):
    def combinationSum(self, candidates, target):
        """
        :type candidates: List[int]
        :type target: int
        :rtype: List[List[int]]
        """
        res = []
        candidates.sort()
        self.DFS(candidates, [], res, target, 0)
        return res
    def DFS(self, candidates, path, res,gap,start):
        #if gap < 0: return
        if gap == 0:
            res.append(path)
            return
        for i in xrange(start, len(candidates)):
            #path.append(candidates[i])
            if gap < candidates[i]: return
            self.DFS(candidates, path + [candidates[i]], res, gap - candidates[i], i)
            #path.pop()
        
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值