Skip to content

Commit ae95a4c

Browse files
author
Zhang Xiaodong
committed
solve 39
1 parent 4356820 commit ae95a4c

File tree

2 files changed

+106
-0
lines changed

2 files changed

+106
-0
lines changed

src/solution/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,4 @@ mod s0035_search_insert_position;
3434
mod s0036_valid_sudoku;
3535
mod s0037_sudoku_solver;
3636
mod s0038_count_and_say;
37+
mod s0039_combination_sum;

src/solution/s0039_combination_sum.rs

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
/**
2+
* [39] 组合总和
3+
*
4+
* 给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ,找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 ,并以列表形式返回。你可以按 任意顺序 返回这些组合。
5+
* candidates 中的 同一个 数字可以 无限制重复被选取 。如果至少一个数字的被选数量不同,则两种组合是不同的。
6+
* 对于给定的输入,保证和为 target 的不同组合数少于 150 个。
7+
*
8+
* 示例 1:
9+
*
10+
* 输入:candidates = [2,3,6,7], target = 7
11+
* 输出:[[2,2,3],[7]]
12+
* 解释:
13+
* 2 和 3 可以形成一组候选,2 + 2 + 3 = 7 。注意 2 可以使用多次。
14+
* 7 也是一个候选, 7 = 7 。
15+
* 仅有这两种组合。
16+
* 示例 2:
17+
*
18+
* 输入: candidates = [2,3,5], target = 8
19+
* 输出: [[2,2,2,2],[2,3,3],[3,5]]
20+
* 示例 3:
21+
*
22+
* 输入: candidates = [2], target = 1
23+
* 输出: []
24+
*
25+
*
26+
* 提示:
27+
*
28+
* 1 <= candidates.length <= 30
29+
* 2 <= candidates[i] <= 40
30+
* candidates 的所有元素 互不相同
31+
* 1 <= target <= 40
32+
*
33+
*/
34+
pub struct Solution {}
35+
36+
// problem: https://leetcode.cn/problems/combination-sum/
37+
// discuss: https://leetcode.cn/problems/combination-sum/discuss/?currentPage=1&orderBy=most_votes&query=
38+
39+
// submission codes start here
40+
41+
impl Solution {
42+
pub fn combination_sum(candidates: Vec<i32>, target: i32) -> Vec<Vec<i32>> {
43+
let mut candidates = candidates.clone();
44+
candidates.sort();
45+
46+
let mut res = vec![];
47+
48+
let mut curr = vec![];
49+
let mut curr_idx = vec![];
50+
let mut sum = 0;
51+
52+
curr.push(candidates[0]);
53+
curr_idx.push(0);
54+
sum += candidates[0];
55+
56+
while curr.len() > 0 {
57+
// println!("{:?} {} {}", curr, sum, target);
58+
if sum < target {
59+
let aidx = curr_idx[curr_idx.len()-1];
60+
curr.push(candidates[aidx]);
61+
curr_idx.push(aidx);
62+
sum += candidates[aidx];
63+
continue;
64+
}
65+
if sum == target {
66+
res.push(curr.clone());
67+
}
68+
while let Some(i) = curr_idx.pop() {
69+
let v = curr.pop().unwrap();
70+
sum -= v;
71+
72+
if i + 1 < candidates.len() {
73+
let i: usize = i + 1;
74+
curr.push(candidates[i]);
75+
curr_idx.push(i);
76+
sum += candidates[i];
77+
break;
78+
}
79+
}
80+
}
81+
res
82+
}
83+
}
84+
85+
// submission codes end
86+
87+
#[cfg(test)]
88+
mod tests {
89+
use super::*;
90+
91+
#[test]
92+
fn test_39() {
93+
let empty_res: Vec<Vec<i32>> = vec![];
94+
95+
assert_eq!(
96+
Solution::combination_sum(vec![2, 3, 6, 7], 7),
97+
vec![vec![2, 2, 3], vec![7]]
98+
);
99+
assert_eq!(Solution::combination_sum(vec![2], 1), empty_res);
100+
assert_eq!(
101+
Solution::combination_sum(vec![2, 3, 5], 8),
102+
vec![vec![2, 2, 2, 2], vec![2, 3, 3], vec![3, 5]]
103+
);
104+
}
105+
}

0 commit comments

Comments
 (0)