您的位置:首页 > 其它

Leetcode: Combination Sum II

2014-10-06 12:10 429 查看
Given a collection of candidate numbers (C) and a target number (T), find all unique combinations in C where the candidate numbers sums to T.

Each number in C may only be used once in the combination.

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 10,1,2,7,6,1,5 and target 8,
A solution set is:
[1, 7]
[1, 2, 5]
[2, 6]
[1, 1, 6]


NP问题,遇到很多次了,这道题跟Combination Sum很像

第二遍方法:注意17行的跳过条件, 我在这里做错过,i > starter 才行, 仅仅i > 0是不行的。 i > starter限制的是一个数的取值不要重复,比如5,5,7,8,第一个数已经取过第一个5了,它就不要再尝试第二个5,但第二个数可以去尝试第二个5,所以第一个数取5同时第二个数也取5是可以的。但是如果把条件写成i > 0,第一个数取了第一个5,第二个数就连第二个5都取不了了,就没有第一个取5第二个也取5这种情况了

public class Solution {
public ArrayList<ArrayList<Integer>> combinationSum2(int[] num, int target) {
ArrayList<ArrayList<Integer>> res = new ArrayList<ArrayList<Integer>>();
ArrayList<Integer> item = new ArrayList<Integer>();
Arrays.sort(num);
helper(res, item, num, target, 0);
return res;
}

public void helper(ArrayList<ArrayList<Integer>> res, ArrayList<Integer> item, int[] num, int remain, int starter) {
if (remain < 0) return;
if (remain == 0) {
res.add(new ArrayList<Integer>(item));
return;
}
for (int i=starter; i<num.length; i++) {
if (i>starter && num[i] == num[i-1]) continue;
item.add(num[i]);
helper(res, item, num, remain-num[i], i+1);
item.remove(item.size()-1);
}
}
}


Naive方法:

public class Solution {
public ArrayList<ArrayList<Integer>> combinationSum2(int[] num, int target) {
ArrayList<ArrayList<Integer>> res = new ArrayList<ArrayList<Integer>>();
if (num == null || num.length == 0) return res;
ArrayList<Integer> path = new ArrayList<Integer>();
Arrays.sort(num);
helper(res, path, num, target, 0, 0);
return res;
}

public void helper(ArrayList<ArrayList<Integer>> res, ArrayList<Integer> path, int[] num, int target, int accum, int index) {
if (accum > target) return;
if (accum == target) {
if (!res.contains(path)) res.add(new ArrayList<Integer>(path));
return;
}
for (int i=index; i<num.length; i++) {
path.add(num[i]);
helper(res, path, num, target, accum+num[i], i+1);
path.remove(path.size()-1);
}
}
}


CodeGanker的做法:注意21行他处理重复的情况,直接跳过

public ArrayList<ArrayList<Integer>> combinationSum2(int[] num, int target) {
ArrayList<ArrayList<Integer>> res = new ArrayList<ArrayList<Integer>>();
if(num == null || num.length==0)
return res;
Arrays.sort(num);
helper(num,0,target,new ArrayList<Integer>(),res);
return res;
}
private void helper(int[] num, int start, int target, ArrayList<Integer> item,
ArrayList<ArrayList<Integer>> res)
{
if(target == 0)
{
res.add(new ArrayList<Integer>(item));
return;
}
if(target<0 || start>=num.length)
return;
for(int i=start;i<num.length;i++)
{
if(i>start && num[i]==num[i-1]) continue;
item.add(num[i]);
helper(num,i+1,target-num[i],item,res);
item.remove(item.size()-1);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: