LeetCode-Combination Sum

问题

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

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

Note:
All numbers (including target) will be positive integers.
Elements in a combination (a1, a2, … , ak) must be in non-descending order. (ie, a1 ≤ a2 ≤ … ≤ ak).
The solution set must not contain duplicate combinations.
For example, given candidate set 2,3,6,7 and target 7,
A solution set is:
[7]
[2, 2, 3]*

思路

由于每个元素可以用多次,针对某个组合来说(以【2,2,3】为例)
1. 首先选中2,那么target还剩下5。第二次还可以选2,3 ,但是不能选6,因为6已经超过target了。迭代重复这个过程。可以选出【2,2,3】。
2. 再次重复这个过程,第一次选3,然后target剩下4,剩下的就不可以选了。

Code

public class Solution {
    public List<List<Integer>> combinationSum(int[] candidates, int target) {
        List<List<Integer>> result = new ArrayList<List<Integer>>();
        if(candidates == null || target < 0){
            return result;
        }
        Arrays.sort(candidates);
        helper(candidates, target, result , new ArrayList<Integer>() , 0);
        return result;
    }

    private void helper(int[] candidates, int target, List<List<Integer>> result, List<Integer> solution , int begin){
        if(target == 0){
            result.add(new ArrayList<Integer>(solution));
            return;
        }

        for(int i = begin ; i < candidates.length && target >= candidates[i] ; i++){
            solution.add(candidates[i]);
            helper(candidates, target-candidates[i] , result , solution , i);
            solution.remove(solution.size() - 1);
        }


    }
}

附加ArrayList的remove方法解析

ArrayList的remove方法有两个重载版本。分别是

public E remove(int);
public boolean remove(Object);

第一个方法是删除指定位置的元素,第二个方法是删除与参数equal的首次出现的元素。那么问题来了,如果List的定义为:

List<Integer> mList = new ArrayList<Integer>();

那到底是删除指定位置的元素还是删除与参数相等的数字呢?

这个要看重载的规律:

参数类型加宽(类型相容) > 自动装箱 > 变长参数

所以,如果mList中的元素有[1,2,3,4,5],我们调用方法:

mList.remove(1)结果变为[1,3,4,5]

再调用mList.remove(new Integer(1)) mList中的元素最终为[3,4,5]

点赞