LeetCode 39. Combination Sum

Description:

Given a set of candidate numbers (candidates) (without duplicates) and a target number (target), find all unique combinations in candidates where the candidate numbers sums to target.

The same repeated number may be chosen from candidates unlimited number of times.

Note:

All numbers (including target) will be positive integers.
The solution set must not contain duplicate combinations.

Solution:

用map储存的dynamic programming
转移方程思想:
i, j 表示的是Integer,AnswerList(i) 表示所有的key为 i 的解集

AnswerList(j) = AnswerList(j - i) + AnswerList(i)

在下面代码中表示:如果key对应的map为空,则返回新建的ArrayList,如果非空,则返回key对应的map值。

sums.computeIfAbsent(candidates[i], (key) -> new ArrayList<>()).add(Arrays.asList(candidates[i])); 

表示返回key对应的map,如果为空,则返回Collections.emptyList()

sums.getOrDefault(target, Collections.emptyList());

思路有点抽象,最好自己手动debug一遍(带入数据一步一步走下去)
总的来说:

  1. 遍历candidates数组,逐个插入,比如2,直接插入2。比如6,插入6之前,已经存在2 2 2 和3 3的list,在后面插入6.
  2. 获取前一步的结果 (sums.get[j - candidates[i]), 在前一步的结果中插入candidates[i] 。比如candidates[i] = 3, j = 5; 则伪代码等价如下思路
//伪代码
map.put(j , map.get(j  - candidates[i]) + candidates[i])

//具体的来写就是
for(int j = candidates[i] + 1; j <= target; j++) {
                List<List<Integer>> sumsSoFar = sums.computeIfAbsent(j - candidates[i], (key) -> new ArrayList<>());
                for(List<Integer> sum : sumsSoFar) {
                    List<Integer> n = new ArrayList<>(sum);
                    n.add(candidates[i]);
                    sums.computeIfAbsent(j, (key) -> new ArrayList<>()).add(n);
                }
            }
  1. 这样一步一步走完,就把各种答案都组合起来了,具体map中值的变化可以debug看看。

综合代码如下:

public List<List<Integer>> combinationSum(int[] candidates, int target) {
        
        Map<Integer, List<List<Integer>>> sums = new HashMap<>();
        
        for(int i = 0; i < candidates.length; ++i) {
            sums.computeIfAbsent(candidates[i], (key) -> new ArrayList<>()).add(Arrays.asList(candidates[i]));
            
            for(int j = candidates[i] + 1; j <= target; j++) {
                List<List<Integer>> sumsSoFar = sums.computeIfAbsent(j - candidates[i], (key) -> new ArrayList<>());
                
                for(List<Integer> sum : sumsSoFar) {
                    List<Integer> n = new ArrayList<>(sum);
                    n.add(candidates[i]);
                    sums.computeIfAbsent(j, (key) -> new ArrayList<>()).add(n);
                }
            }
        }   
        return sums.getOrDefault(target, Collections.emptyList());
    }
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值