题目:

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]

链接: http://leetcode.com/problems/combination-sum-ii/

题解:

依然是一道DFS + Backtracking题目。 与之前不同的是每个数字只允许使用一次。所以在回溯的循环里当 i > pos时,假如之后又重复的,continue。我们依然使用candidates[i],而且candidates[i + 1]假如等于candidates[i], 会在DFS的下一个阶段被使用到。当然假如不用这个巧妙的条件也可以, 可以在 target == 0的时候判断res中是否contains  list,这样的话运行速度会慢不少,但也可以AC.

Time Complexity - O(), Space Complexity - O()。 如何计算复杂度,智商捉急啊...

public class Solution {
public List<List<Integer>> combinationSum2(int[] candidates, int target) {
List<List<Integer>> res = new ArrayList<>();
if(candidates == null || candidates.length == 0)
return res;
Arrays.sort(candidates);
ArrayList<Integer> list = new ArrayList<>();
dfs(res, list, candidates, target, 0);
return res;
} private void dfs(List<List<Integer>> res, ArrayList<Integer> list, int[] candidates, int target, int pos) {
if(target == 0) {
res.add(new ArrayList<Integer>(list));
return;
}
if(pos >= candidates.length || target < 0)
return; for(int i = pos; i < candidates.length; i++) {
if(i > pos && candidates[i] == candidates[i - 1]) //for i > pos, if duplicate,continue. we still use candidates[i]
continue;
list.add(candidates[i]);
dfs(res, list, candidates, target - candidates[i], i + 1);
list.remove(list.size() - 1);
}
}
}

二刷:

这里依然是用了跟上一题目很接近的方法。不同的地方在于,每个数字不可以被无限次。所以一个数只能一次,而且遇到重复数字我们要跳过。这样我们在for循环里要加入一条 -  if (i > pos && candidates[i] == candidates[i - 1]) continue; 并且在DFS的时候每次

每次新的position = i + 1, 并不是上一题的position = i。

看到有discuss里有方法用array来做backtracking,速度beat 99%,以后也可以把list改成array,试一试这种方法。

Java:

public class Solution {
public List<List<Integer>> combinationSum2(int[] candidates, int target) {
List<List<Integer>> res = new ArrayList<>();
if (candidates == null || candidates.length == 0) {
return res;
}
Arrays.sort(candidates);
List<Integer> comb = new ArrayList<>();
combinationSum2(res, comb, candidates, target, 0);
return res;
} private void combinationSum2(List<List<Integer>> res, List<Integer> comb, int[] candidates, int target, int pos) {
if (target < 0) {
return;
} else if (target == 0) {
res.add(new ArrayList<>(comb));
}
for (int i = pos; i < candidates.length; i++) {
if (i > pos && candidates[i] == candidates[i - 1]) {
continue;
}
int num = candidates[i];
if (num > target) {
return;
}
comb.add(num);
combinationSum2(res, comb, candidates, target - num, i + 1);
comb.remove(comb.size() - 1);
}
}
}

三刷:

跟上题唯一不同就是递归时把控制position的变量从 i 变成了 i + 1,这样我们就不会对一个元素进行多次计算。

Java:

public class Solution {
public List<List<Integer>> combinationSum2(int[] candidates, int target) {
List<List<Integer>> res = new ArrayList<>();
if (candidates == null) return res;
Arrays.sort(candidates);
findCombinations(res, new ArrayList<>(), candidates, target, 0);
return res;
} private void findCombinations(List<List<Integer>> res, List<Integer> list, int[] candidates, int target, int pos) {
if (target < 0) return;
if (target == 0) {
res.add(new ArrayList<>(list));
return;
}
for (int i = pos; i < candidates.length; i++) {
if (candidates[i] > target) break;
if (i > pos && candidates[i] == candidates[i - 1]) continue;
list.add(candidates[i]);
findCombinations(res, list, candidates, target - candidates[i], i + 1);
list.remove(list.size() - 1);
}
}
}

Reference:

https://leetcode.com/submissions/detail/51501884/

40. Combination Sum II的更多相关文章

  1. [Leetcode][Python]40: Combination Sum II

    # -*- coding: utf8 -*-'''__author__ = 'dabay.wang@gmail.com' 40: Combination Sum IIhttps://oj.leetco ...

  2. [array] leetcode - 40. Combination Sum II - Medium

    leetcode - 40. Combination Sum II - Medium descrition Given a collection of candidate numbers (C) an ...

  3. leetcode 39. Combination Sum 、40. Combination Sum II 、216. Combination Sum III

    39. Combination Sum 依旧与subsets问题相似,每次选择这个数是否参加到求和中 因为是可以重复的,所以每次递归还是在i上,如果不能重复,就可以变成i+1 class Soluti ...

  4. 【LeetCode】40. Combination Sum II (2 solutions)

    Combination Sum II Given a collection of candidate numbers (C) and a target number (T), find all uni ...

  5. [LeetCode] 40. Combination Sum II 组合之和之二

    Given a collection of candidate numbers (candidates) and a target number (target), find all unique c ...

  6. 【LeetCode题意分析&解答】40. Combination Sum II

    Given a collection of candidate numbers (C) and a target number (T), find all unique combinations in ...

  7. LeetCode OJ 40. Combination Sum II

    Given a collection of candidate numbers (C) and a target number (T), find all unique combinations in ...

  8. 【一天一道LeetCode】#40. Combination Sum II

    一天一道LeetCode系列 (一)题目 Given a collection of candidate numbers (C) and a target number (T), find all u ...

  9. [leetcode]40. Combination Sum II组合之和之二

    Given a collection of candidate numbers (candidates) and a target number (target), find all unique c ...

  10. 39. Combination Sum + 40. Combination Sum II + 216. Combination Sum III + 377. Combination Sum IV

    ▶ 给定一个数组 和一个目标值.从该数组中选出若干项(项数不定),使他们的和等于目标值. ▶ 36. 数组元素无重复 ● 代码,初版,19 ms .从底向上的动态规划,但是转移方程比较智障(将待求数分 ...

随机推荐

  1. TDirectory.CreateDirectory 完整、严谨的创建一个目录

    描述:创建一个目录,不包含多级目录(多级目录使用System.SysUtils.ForceDirectories,Vcl.FileCtrl.ForceDirectories已过时) procedure ...

  2. asp.net 生成PDF方法

    今天转博客园看到有人发表了一篇生成PFd的文章,准备自己也留一份准备以后用到的时候方便调用: 首先去itextsharp网站下载控件(https://sourceforge.net/projects/ ...

  3. hdu 5690 2016"百度之星" - 初赛(Astar Round2A) All X 快速二次幂 || 寻找周期

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5690 题意:m个数字全为x mod k ?= c;其中m <= 1010,0 < c,k ...

  4. Input event驱动

    Input event驱动 Linux 专门对输入设备. 键盘,鼠标,手柄,触摸屏.按键.封装一个类驱动. 主要统一与应用程序接口.这一类的设备结点都是在/dev/input/eventn( 0< ...

  5. active-mq的使用

    1.下载ActiveMQ 去官方网站下载:http://activemq.apache.org/ 2.运行ActiveMQ 解压缩apache-activemq-5.5.1-bin.zip,然后双击a ...

  6. 使用PHP计算上一个月的今天

    一日,遇到一个问题,求上一个月的今天. 最开始我们使用 strtotime(“-1 month”) 函数求值,发现有一个问题,月长度不一样的月份的计算结果有误. 比如:2011-03-31,得到的结果 ...

  7. advance 模板 怎么生成module

    advance 模板 怎么生成module namespace写什么如果是前台呢就是 frontend\modules\modulename\Module@我叫红领巾 module id有什么用bak ...

  8. 实现iOS长时间后台的两种方法:Audiosession和VOIP(转)

    分类: Iphone2013-01-24 14:03 986人阅读 评论(0) 收藏 举报 我们知道iOS开启后台任务后可以获得最多600秒的执行时间,而一些需要在后台下载或者与服务器保持连接的App ...

  9. Android journey 2 @Android系统框架

    此刻,本人还是一个android菜鸟,刚刚开始起步学习android相关知识,想用blog记录自己学习的过程,一方面给他人提供帮助,另一方面给自己个复习的地方. 在一起学习Android之前,先跟大家 ...

  10. Visual Studio 2013无法打开IIS Express Web的解决办法

    1. 首先参考了http://www.cr173.com/html/33412_1.html 2. 参考其最后,从微软官网下载安装WebMatrix,打开WebMatrix. 3. Visual St ...