算法leetcode|39. 组合总和(rust重拳出击)

Posted 二当家的白帽子

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法leetcode|39. 组合总和(rust重拳出击)相关的知识,希望对你有一定的参考价值。


文章目录


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 <= candidates.length <= 30
  • 2 <= candidates[i] <= 40
  • candidates 的所有元素 互不相同
  • 1 <= target <= 40

分析:

  • 面对这道算法题目,二当家的陷入了沉思。
  • 遍历或者递归,递归比较直观,深度优先,回溯。
  • 题目要求所有可能的组合,不能重复,本来是需要想办法去重的,但是题目规定参数中所有元素互不相同,那我们只要选择不同下标的组合就相当于选择了不同元素的组合。

题解:

rust

impl Solution 
    pub fn combination_sum(candidates: Vec<i32>, target: i32) -> Vec<Vec<i32>> 
        fn dfs(candidates: &Vec<i32>, target: i32, idx: usize, row: &mut Vec<i32>, ans: &mut Vec<Vec<i32>>) 
            if idx == candidates.len() 
                // 尝试到底,开始回溯
                return;
            
            if target == 0 
                // 符合条件的一个组合
                ans.push(row.clone());
                return;
            
            if target >= candidates[idx] 
                // 选择当前下标数字
                row.push(candidates[idx]);
                dfs(candidates, target - candidates[idx], idx, row, ans);
                row.pop();
            
            // 跳过当前下标数字
            dfs(candidates, target, idx + 1, row, ans);
        

        let mut ans = Vec::new();
        dfs(&candidates, target, 0, &mut Vec::new(), &mut ans);

        return ans;
    


go

func combinationSum(candidates []int, target int) [][]int 
    var ans [][]int

	var dfs func(int, int, []int)
	dfs = func(target int, idx int, row []int) 
		if idx == len(candidates) 
			// 尝试到底,开始回溯
			return
		
		if target == 0 
			// 符合条件的一个组合
			ans = append(ans, append([]int, row...))
			return
		
		// 选择当前下标数字
		if target >= candidates[idx] 
			row = append(row, candidates[idx])
			dfs(target-candidates[idx], idx, row)
			row = row[:len(row)-1]
		
		// 跳过当前下标数字
		dfs(target, idx+1, row)
	

	dfs(target, 0, []int)

	return ans


c++

class Solution 
private:
    void dfs(vector<int>& candidates, int target, int idx, vector<int>& row, vector<vector<int>>& ans) 
        if (idx == candidates.size()) 
            // 尝试到底,开始回溯
            return;
        
        if (target == 0) 
            // 符合条件的一个组合
            ans.emplace_back(row);
            return;
        
        // 选择当前下标数字
        if (target >= candidates[idx]) 
            row.emplace_back(candidates[idx]);
            dfs(candidates, target - candidates[idx], idx, row, ans);
            row.pop_back();
        
        // 跳过当前下标数字
        dfs(candidates, target, idx + 1, row, ans);
    
public:
    vector<vector<int>> combinationSum(vector<int>& candidates, int target) 
        vector<vector<int>> ans;
        vector<int> row;
        dfs(candidates, target, 0, row, ans);
        return ans;
    
;

c

void dfs(int *candidates, int candidatesSize, int target, int idx, int *row, int rowSize, int **ans, int *returnSize,
         int **returnColumnSizes) 
    if (idx == candidatesSize) 
        // 尝试到底,开始回溯
        return;
    
    if (target == 0) 
        // 符合条件的一个组合
        ans[*returnSize] = (int *) malloc(sizeof(int) * rowSize);
        memcpy(ans[*returnSize], row, sizeof(int) * rowSize);
        (*returnColumnSizes)[*returnSize] = rowSize;
        ++(*returnSize);
        return;
    
    // 选择当前下标数字
    if (target >= candidates[idx]) 
        row[rowSize] = candidates[idx];
        dfs(candidates, candidatesSize, target - candidates[idx], idx, row, rowSize + 1, ans, returnSize,
            returnColumnSizes);
    
    // 跳过当前下标数字
    dfs(candidates, candidatesSize, target, idx + 1, row, rowSize, ans, returnSize, returnColumnSizes);


/**
 * Return an array of arrays of size *returnSize.
 * The sizes of the arrays are returned as *returnColumnSizes array.
 * Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
 */
int **combinationSum(int *candidates, int candidatesSize, int target, int *returnSize, int **returnColumnSizes) 
    *returnSize = 0;
    *returnColumnSizes = (int *) malloc(sizeof(int) * 150);
    int **ans = (int **) malloc(sizeof(int *) * 150);
    int row[target];
    dfs(candidates, candidatesSize, target, 0, row, 0, ans, returnSize, returnColumnSizes);
    return ans;


python

class Solution:
    def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:
        ans = []

        def dfs(target: int, idx: int, row: List[int]):
            if idx == len(candidates):
                # 尝试到底,开始回溯
                return
            if target == 0:
                # 符合条件的一个组合
                ans.append(row.copy())
                return
            # 选择当前下标数字
            if target >= candidates[idx]:
                row.append(candidates[idx])
                dfs(target - candidates[idx], idx, row)
                row.pop()
            # 跳过当前下标数字
            dfs(target, idx + 1, row)

        dfs(target, 0, [])
        return ans


java

class Solution 
    public List<List<Integer>> combinationSum(int[] candidates, int target) 
        List<List<Integer>> ans = new ArrayList<>();
        this.dfs(candidates, target, 0, new LinkedList<>(), ans);
        return ans;
    

    private void dfs(int[] candidates, int target, int idx, Deque<Integer> row, List<List<Integer>> ans) 
        if (idx == candidates.length) 
            // 尝试到底,开始回溯
            return;
        
        if (target == 0) 
            // 符合条件的一个组合
            ans.add(new ArrayList<>(row));
            return;
        
        if (target >= candidates[idx]) 
            // 选择当前下标数字
            row.addLast(candidates[idx]);
            this.dfs(candidates, target - candidates[idx], idx, row, ans);
            row.pollLast();
        
        // 跳过当前下标数字
        this.dfs(candidates, target, idx + 1, row, ans);
    


非常感谢你阅读本文~
欢迎【点赞】【收藏】【评论】~
放弃不难,但坚持一定很酷~
希望我们大家都能每天进步一点点~
本文由 二当家的白帽子:https://le-yi.blog.csdn.net/ 博客原创~


以上是关于算法leetcode|39. 组合总和(rust重拳出击)的主要内容,如果未能解决你的问题,请参考以下文章

Leetcode 39 组合总和(回溯算法解题)

LeetCode[39]: 组合总和

Python描述 LeetCode 39. 组合总和

leetcode 40. 组合总和 II---回溯篇3

算法 ---- LeetCode回溯系列问题题解

算法 ---- LeetCode回溯系列问题题解