40. Combination Sum II
题目:
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的更多相关文章
- [Leetcode][Python]40: Combination Sum II
# -*- coding: utf8 -*-'''__author__ = 'dabay.wang@gmail.com' 40: Combination Sum IIhttps://oj.leetco ...
- [array] leetcode - 40. Combination Sum II - Medium
leetcode - 40. Combination Sum II - Medium descrition Given a collection of candidate numbers (C) an ...
- leetcode 39. Combination Sum 、40. Combination Sum II 、216. Combination Sum III
39. Combination Sum 依旧与subsets问题相似,每次选择这个数是否参加到求和中 因为是可以重复的,所以每次递归还是在i上,如果不能重复,就可以变成i+1 class Soluti ...
- 【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 ...
- [LeetCode] 40. Combination Sum II 组合之和之二
Given a collection of candidate numbers (candidates) and a target number (target), find all unique c ...
- 【LeetCode题意分析&解答】40. Combination Sum II
Given a collection of candidate numbers (C) and a target number (T), find all unique combinations in ...
- LeetCode OJ 40. Combination Sum II
Given a collection of candidate numbers (C) and a target number (T), find all unique combinations in ...
- 【一天一道LeetCode】#40. Combination Sum II
一天一道LeetCode系列 (一)题目 Given a collection of candidate numbers (C) and a target number (T), find all u ...
- [leetcode]40. Combination Sum II组合之和之二
Given a collection of candidate numbers (candidates) and a target number (target), find all unique c ...
- 39. Combination Sum + 40. Combination Sum II + 216. Combination Sum III + 377. Combination Sum IV
▶ 给定一个数组 和一个目标值.从该数组中选出若干项(项数不定),使他们的和等于目标值. ▶ 36. 数组元素无重复 ● 代码,初版,19 ms .从底向上的动态规划,但是转移方程比较智障(将待求数分 ...
随机推荐
- Selenium 入门
我本身也是一个初学者,就顺手记录一下自己的成长记录,共勉 1, 登录selenium官方网站,download 相关的插件. http://docs.seleniumhq.org/ 我用的是eclip ...
- android studio安装插件
1.File-Settings菜单
- 通过替换frm文件方式修改表结构
版本:5.6.16 在自己的虚拟环境中,测试创建一个表,表结构如下:mysql> drop table yoon_temp;Query OK, 0 rows affected (0.09 sec ...
- Linux命令练级初级
Linux命令练级初级 http://ke.qq.com/video/index.html?course_id=6815 ls -a 所有文件 -l 类型,连接数,所属用户,工作组, ...
- Web开发从零单排之二:在自制电子请帖中添加留言板功能,SAE+PHP+MySql
在上一篇博客中介绍怎样在SAE平台搭建一个html5的电子请帖网站,收到很多反馈,也有很多人送上婚礼的祝福,十分感谢! web开发从零学起,记录自己学习过程,各种前端大神们可以绕道不要围观啦 大婚将至 ...
- NodeJS从零开始——NPM的使用
NPM是一个Node包管理和分发工具,已经成为了非官方的发布Node模块(包)的标准.有了NPM,可以很快的找到特定服务要使用的包,进行下载.安装以及管理已经安装的包. NPM常用的命令有: (1)$ ...
- linux作业六——进程的描述和进程的创建
进程的描述和进程的创建 一.进程描述符task_struct 为了管理进程,内核必须对每个进程进行清晰的描述,进程描述符提供了内核所需了解的进程信息. 代码关键点: 1.Struct list_hea ...
- (转)使用 /proc 文件系统来访问 Linux 内核的内容
转载网址:http://www.ibm.com/developerworks/cn/linux/l-proc.html 这个虚拟文件系统在内核空间和用户空间之间打开了一个通信窗口/proc 文件系统是 ...
- 利用JavaScript获取页面文档内容
JavaScript的document对象包含了页面的实际内容,所以利用document对象可以获取页面内容,例如页面标题.各个表单值. <!DOCTYPE html> <html ...
- segment fault
http://blog.chinaunix.net/uid-23069658-id-3959636.html