• 【算法leetcode】剑指 Offer II 081. 允许重复选择元素的组合(多语言实现)




    剑指 Offer II 081. 允许重复选择元素的组合:

    给定一个无重复元素的正整数数组 candidates 和一个正整数 target ,找出 candidates 中所有可以使数字和为目标数 target 的唯一组合。

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

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

    样例 1:

    输入: 
    	candidates = [2,3,6,7], target = 7
    	
    输出: 
    	[[7],[2,2,3]]
    
    • 1
    • 2
    • 3
    • 4
    • 5

    样例 2:

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

    样例 3:

    输入: 
    	candidates = [2], target = 1
    	
    输出: 
    	[]
    
    • 1
    • 2
    • 3
    • 4
    • 5

    样例 4:

    输入: 
    	candidates = [1], target = 1
    	
    输出: 
    	[[1]]
    
    • 1
    • 2
    • 3
    • 4
    • 5

    样例 5:

    输入: 
    	candidates = [1], target = 2
    	
    输出: 
    	[[1,1]]
    
    • 1
    • 2
    • 3
    • 4
    • 5

    提示:

    • 1 <= candidates.length <= 30
    • 1 <= candidates[i] <= 200
    • candidate 中的每个元素都是独一无二的。
    • 1 <= target <= 500

    分析

    • 面对这道算法题目,二当家的陷入了沉思。
    • 最直观的方式就是递归套娃大法了。
    • 每个数字都可以选择,或者不选择。
    • 需要注意的就是每个数字都是可以重复选择的,由于是组合,所以我们就遍历数组,按顺序选择(选择当前数字或者跳过当前数字),直到和大于等于目标值。

    题解

    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 target == 0 {
                    // 符合条件的一个组合
                    ans.push(row.clone());
                    return;
                }
                if idx >= candidates.len() {
                    // 尝试到底,开始回溯
                    return;
                }
                // 跳过当前下标数字
                dfs(candidates, target, idx + 1, row, ans);
                // 选择当前下标数字
                if target - candidates[idx] >= 0 {
                    row.push(candidates[idx]);
                    dfs(candidates, target - candidates[idx], idx, row, ans);
                    row.pop();
                }
            }
    
            let mut ans = Vec::new();
            dfs(&candidates, target, 0, &mut Vec::new(), &mut ans);
            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
    • 25
    • 26
    • 27

    go

    func combinationSum(candidates []int, target int) [][]int {
        var ans [][]int
    
    	var dfs func(int, int, []int, int)
    	dfs = func(target int, idx int, row []int, rowSize int) {
    		if target == 0 {
    			// 符合条件的一个组合
    			ans = append(ans, append([]int{}, row[0:rowSize]...))
    			return
    		}
    		if idx >= len(candidates) {
    			// 尝试到底,开始回溯
    			return
    		}
    		// 跳过当前下标数字
    		dfs(target, idx+1, row, rowSize)
    		// 选择当前下标数字
    		if target-candidates[idx] >= 0 {
    			row[rowSize] = candidates[idx]
    			dfs(target-candidates[idx], idx, row, rowSize+1)
    		}
    	}
    
    	dfs(target, 0, make([]int, target), 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
    • 25
    • 26
    • 27

    typescript

    function combinationSum(candidates: number[], target: number): number[][] {
        function dfs(target: number, idx: number, row: number[]) {
    		if (target == 0) {
    			// 符合条件的一个组合
    			ans.push([...row]);
    			return;
    		}
    		if (idx >= candidates.length) {
    			// 尝试到底,开始回溯
    			return;
    		}
    		// 跳过当前下标数字
    		dfs(target, idx + 1, row);
    		// 选择当前下标数字
    		if (target - candidates[idx] >= 0) {
    			row.push(candidates[idx]);
    			dfs(target - candidates[idx], idx, row);
    			row.pop();
    		}
    	}
    
    	const ans = [];
    	dfs(target, 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
    • 25

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

    c

    void dfs(int *candidates, int candidatesSize, int target, int idx, int *row, int rowSize, int **ans, int *returnSize,
             int **returnColumnSizes) {
        if (target == 0) {
            // 符合条件的一个组合
            ans[*returnSize] = (int *) malloc(sizeof(int) * rowSize);
            memcpy(ans[*returnSize], row, sizeof(int) * rowSize);
            (*returnColumnSizes)[*returnSize] = rowSize;
            ++(*returnSize);
            return;
        }
        if (idx >= candidatesSize) {
            // 尝试到底,开始回溯
            return;
        }
        // 跳过当前下标数字
        dfs(candidates, candidatesSize, target, idx + 1, row, rowSize, ans, returnSize, returnColumnSizes);
        // 选择当前下标数字
        if (target - candidates[idx] >= 0) {
            row[rowSize] = candidates[idx];
            dfs(candidates, candidatesSize, target - candidates[idx], idx, row, rowSize + 1, 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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    c++

    class Solution {
    private:
        void dfs(vector<int>& candidates, int target, int idx, vector<int>& row, vector<vector<int>>& ans) {
            if (target == 0) {
                // 符合条件的一个组合
                ans.emplace_back(row);
                return;
            }
            if (idx >= candidates.size()) {
                // 尝试到底,开始回溯
                return;
            }
            // 跳过当前下标数字
            dfs(candidates, target, idx + 1, row, ans);
            // 选择当前下标数字
            if (target - candidates[idx] >= 0) {
                row.emplace_back(candidates[idx]);
                dfs(candidates, target - candidates[idx], idx, row, ans);
                row.pop_back();
            }
        }
    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;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    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 (target == 0) {
                // 符合条件的一个组合
                ans.add(new ArrayList<>(row));
                return;
            }
            if (idx >= candidates.length) {
                // 尝试到底,开始回溯
                return;
            }
            // 跳过当前下标数字
            this.dfs(candidates, target, idx + 1, row, ans);
            // 选择当前下标数字
            if (target - candidates[idx] >= 0) {
                row.addLast(candidates[idx]);
                this.dfs(candidates, target - candidates[idx], idx, row, ans);
                row.pollLast();
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    原题传送门:https://leetcode.cn/problems/Ygoe9J/submissions/


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


  • 相关阅读:
    hdfs笔记
    CREO:利用CREO软件实现装配设计之四连杆机构设计案例应用(图文教程)之详细攻略
    java基于SpringBoot+vue的餐厅点餐外卖系统 elementui 前后端分离
    GZ031 应用软件系统开发赛题第1套
    混合劳动力情况下需要的 3 种移动工具
    每天五分钟机器学习:数据和特征决定机器学习的上限(特征工程)
    少数人的晚餐-数据
    有哪些可助力英文学术论文写作的在线网站、工具或软件?
    1089 Insert or Merge
    102. 二叉树的层序遍历
  • 原文地址:https://blog.csdn.net/leyi520/article/details/125393734