2021/04/05
题目描述
给定一个数组candidates
和一个目标数target
,找出candidates
中所有可以使数字和为target
的组合。
candidates
中的每个数字在每个组合中只能使用一次。
分析
这道题有部分剪枝逻辑类似有重复元素的全排列。
实现
impl Solution {
pub fn combination_sum2(mut candidates: Vec<i32>, target: i32) -> Vec<Vec<i32>> {
let mut result = vec![];
let mut vis: Vec<_> = candidates.iter().map(|i| false).collect();
candidates.sort();
Solution::combination_sum0(&candidates, target, &mut vec![], &mut vis, &mut result);
return result;
}
fn combination_sum0(candidates: &Vec<i32>, target: i32, cur: &mut Vec<i32>, vis: &mut Vec<bool>, result: &mut Vec<Vec<i32>>) {
if target == 0 {
result.push(cur.clone());
return;
}
for (idx, it) in candidates.iter().enumerate() {
// 已经使用过,或没有符合条件的数
if it > &target || vis[idx] {
continue;
}
// 类似带重复元素的全排列,如果前一个元素跟这个元素相同,且没有使用过,那这个元素也不要使用了
if idx > 0 && candidates[idx] == candidates[idx - 1] && vis[idx - 1] == false {
continue;
}
// 保证结果集数组是升序的
if cur.len() > 0 && it < cur.last().unwrap() {
continue;
}
cur.push(*it);
vis[idx] = true;
Solution::combination_sum0(candidates, target - *it, cur, vis, result);
vis[idx] = false;
cur.pop();
}
}
}