YSMull
<-- algorithm



原题链接

题目描述

给定一个数组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();
        }
    }
}