给定一个无重复元素的正整数数组 candidates 和一个正整数 target ,找出 candidates 中所有可以使数字和为目标数 target 的唯一组合。
candidates 中的数字可以无限制重复被选取。如果至少一个所选数字数量不同,则两种组合是不同的。
对于给定的输入,保证和为 target 的唯一组合数少于 150 个。
输入:
candidates = [2,3,6,7], target = 7
输出:
[[7],[2,2,3]]
输入:
candidates = [2,3,5], target = 8
输出:
[[2,2,2,2],[2,3,3],[3,5]]
输入:
candidates = [2], target = 1
输出:
[]
输入:
candidates = [1], target = 1
输出:
[[1]]
输入:
candidates = [1], target = 2
输出:
[[1,1]]
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
}
}
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
}
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;
};
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
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;
}
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;
}
};
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://le-yi.blog.csdn.net/ 博客原创~