算法leetcode剑指 Offer II 081. 允许重复选择元素的组合(多语言实现)
Posted 二当家的白帽子
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法leetcode剑指 Offer II 081. 允许重复选择元素的组合(多语言实现)相关的知识,希望对你有一定的参考价值。
文章目录
- 剑指 Offer II 081. 允许重复选择元素的组合:
- 样例 1:
- 样例 2:
- 样例 3:
- 样例 4:
- 样例 5:
- 提示:
- 分析
- 题解
- 原题传送门:https://leetcode.cn/problems/Ygoe9J/submissions/
剑指 Offer II 081. 允许重复选择元素的组合:
给定一个无重复元素的正整数数组 candidates
和一个正整数 target
,找出 candidates
中所有可以使数字和为目标数 target
的唯一组合。
candidates
中的数字可以无限制重复被选取。如果至少一个所选数字数量不同,则两种组合是不同的。
对于给定的输入,保证和为 target
的唯一组合数少于 150
个。
样例 1:
输入:
candidates = [2,3,6,7], target = 7
输出:
[[7],[2,2,3]]
样例 2:
输入:
candidates = [2,3,5], target = 8
输出:
[[2,2,2,2],[2,3,3],[3,5]]
样例 3:
输入:
candidates = [2], target = 1
输出:
[]
样例 4:
输入:
candidates = [1], target = 1
输出:
[[1]]
样例 5:
输入:
candidates = [1], target = 2
输出:
[[1,1]]
提示:
- 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
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
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;
;
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
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;
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;
;
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();
原题传送门:https://leetcode.cn/problems/Ygoe9J/submissions/
非常感谢你阅读本文~
欢迎【点赞】【收藏】【评论】~
放弃不难,但坚持一定很酷~
希望我们大家都能每天进步一点点~
本文由 二当家的白帽子:https://le-yi.blog.csdn.net/ 博客原创~
以上是关于算法leetcode剑指 Offer II 081. 允许重复选择元素的组合(多语言实现)的主要内容,如果未能解决你的问题,请参考以下文章
算法leetcode剑指 Offer 56 - II. 数组中数字出现的次数 II(多语言实现)
算法leetcode剑指 Offer 56 - II. 数组中数字出现的次数 II(多语言实现)
算法leetcode剑指 Offer II 041. 滑动窗口的平均值(rust重拳出击)
算法leetcode剑指 Offer II 041. 滑动窗口的平均值(rust重拳出击)