LeetCode每日一题(216. Combination Sum III)

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

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
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值