Find all valid combinations of k numbers that sum up to n such that the following conditions are true:
Only numbers 1 through 9 are used.
Each number is used at most once.
Return a list of all possible valid combinations. The list must not contain the same combination twice, and the combinations may be returned in any order.
Example 1:
Input: k = 3, n = 7
Output: [[1,2,4]]
Explanation:
1 + 2 + 4 = 7
There are no other valid combinations.
Example 2:
Input: k = 3, n = 9
Output: [[1,2,6],[1,3,5],[2,3,4]]
Explanation:
1 + 2 + 6 = 9
1 + 3 + 5 = 9
2 + 3 + 4 = 9
There are no other valid combinations.
Example 3:
Input: k = 4, n = 1
Output: []
Explanation: There are no valid combinations.
Using 4 different numbers in the range [1,9], the smallest sum we can get is 1+2+3+4 = 10 and since 10 > 1, there are no valid combination.
Constraints:
- 2 <= k <= 9
- 1 <= n <= 60
以前用 golang 实现过一次, 这次换 rust 来实现, 结果被一个小失误绊了一个多小时
用 dp 来解, dp[k][d][curr]代表还剩余 k 次挑选机会,与目标数 n 的差异为 d,当前数字为 curr 的情况下的所有组合, 要注意的是, 我们的 curr 一定得是单向递增的, 这样才不会出现挑选重复数字的情况。但是要注意的是, 最终返回边界条件是 k1 且 dcurr, 最开始我认为只要 d >= curr 且 d < 9 就可以返回, 但是这样会导致出现重复的组合。
use std::collections::HashMap;
impl Solution {
fn dp(k: i32, n: i32, curr: i32, cache: &mut HashMap<(i32, i32, i32), Vec<Vec<i32>>>) -> Vec<Vec<i32>> {
let mut ans = Vec::new();
if k == 1 {
if n == curr {
return vec![vec![n]];
}
return ans;
}
for i in curr + 1..10 {
let mut next = if let Some(c) = cache.get(&(k - 1, n - curr, i)) {
c.clone()
} else {
Solution::dp(k - 1, n - curr, i, cache)
};
next.iter_mut().for_each(|l| l.push(curr));
ans.extend(next);
}
cache.insert((k, n, curr), ans.clone());
ans
}
pub fn combination_sum3(k: i32, n: i32) -> Vec<Vec<i32>> {
let mut ans = Vec::new();
let mut cache = HashMap::new();
for i in 1..10 {
let next = Solution::dp(k, n, i, &mut cache);
ans.extend(next);
}
ans
}
}

给定k和n,找到1到9中不重复的k个数字,使它们的和等于n。文章通过一个例子解释了问题,并提到之前使用Golang解决过,这次用Rust实现时遇到一个小错误,通过动态规划(dp)解决,其中dp[k][d][curr]表示剩余挑选次数、与目标差值及当前数字的情况。注意curr必须递增,避免重复数字。最终返回的边界条件是k=1且d=curr,最初错误的边界条件导致了重复组合。
510

被折叠的 条评论
为什么被折叠?



