数字组合问题:Combination,CombinationSum,CombinationSum2,CombinationSum3
Combination问题描述:给定n和k,找出1-n之间所有k个数的组合,例如:n=3,k=2,返回
[[1,2] [1,3] [2,3]]
算法分析:利用递归。递归边界就是curr.size()==k。
public List<List<Integer>> combine(int n, int k)
{
List<List<Integer>> result = new ArrayList<>();
List<Integer> current = new ArrayList<>();
if(n <= 0 || n<k)
{
return result;
}
combine(n, k, 1, current, result);
return result;
}
//递归和n,k无关,只是边界条件和k相关,n,k在递归中不变化。
public void combine(int n, int k, int start, List<Integer> current, List<List<Integer>> result)
{
if(current.size() == k)
{
List<Integer> temp = new ArrayList<>(current);
result.add(temp);
return ;
}
for(int i = start; i <= n; i ++)
{
current.add(i);
combine(n, k, i+1, current, result);
current.remove(current.size()-1);
}
}
CombinationSum问题描述:给一组数字和target,这组数字没有重复元素,找出这组数字中相加为target的集合。
例如给定set[2,3,6,7]和target=7.返回[[7] [2,2,3]]. 也就是说,数字集合没有重复,但是结果集里面可以重复某个元素。先把数据集排序。
算法分析:利用递归,边界条件是target==0.
public List<List<Integer>> combinationSum(int[] candidates, int target)
{
List<List<Integer>> result = new ArrayList<>();
List<Integer> current = new ArrayList<>();
if(candidates == null || candidates.length == 0)
{
return result;
}
Arrays.sort(candidates);
combinationSum(candidates, target, 0, current, result);
return result;
} public void combinationSum(int[] candidates, int target, int i, List<Integer> curr, List<List<Integer>> result)
{
if(target == 0)//组合成功
{
List<Integer> temp = new ArrayList<>(curr);
result.add(temp);
return;
}
for(int j = i; j < candidates.length; j ++)
{
if(target < candidates[j])
{
return ;
}
curr.add(candidates[j]);
combinationSum(candidates, target-candidates[j], j, curr, result);
//如果上一步递归返回则去掉最后加入的元素,然后回溯。
//curr.remove(candidates[j]);错误,list的参数是index
curr.remove(curr.size()-1);
}
}
CombinationSum2问题描述:给定数据集里面有重复元素,但是结果集中每个数据集中的元素只能出现一次。
例如:[10, 1, 2, 7, 6, 1, 5],target=8,返回 17 125 26 116
算法分析:递归的下标要取j+1,然后还要过滤相同序列。使用hashset。
public List<List<Integer>> combinationSum2(int[] candidates, int target) {
List<List<Integer>> result = new ArrayList<>();
List<Integer> current = new ArrayList<>();
if(candidates == null || candidates.length == 0)
{
return result;
}
Arrays.sort(candidates);
combinationSum2(candidates, target, 0, current, result);
//利用hashset过滤重复元素
HashSet<List<Integer>> set = new HashSet<>(result);
result.clear();
result.addAll(set);
return result;
} public void combinationSum2(int[] candidates, int target, int i, List<Integer> curr, List<List<Integer>> result)
{
if(target == 0)
{
List<Integer> temp = new ArrayList<>(curr);
result.add(temp);
return;
}
for(int j = i; j < candidates.length; j ++)
{
if(candidates[j] > target)
{
return;
}
curr.add(candidates[j]);
//下标j+1,过滤相同元素
combinationSum2(candidates, target-candidates[j], j + 1, curr, result);
curr.remove(curr.size()-1);
}
}
CombinationSum3:给定k和target,找到1-9集合中满足k个数的和=target的序列集合。
例如:k=3,target=6.返回123 , k=3, target=9,返回126,135,234
算法分析:这道题和3Sum很像,因为3Sum不能用递归,因为时间复杂度太高。还有一类问题,就是说i<j<k, 返回i,j,k,,满足i+j+k=target
这种只能用三层for循环了,因为没有数据集的限制。
public List<List<Integer>> combinationSum3(int k, int n) {
List<List<Integer>> result = new ArrayList<>();
List<Integer> curr = new ArrayList<>();
combinationSum3(k, n, 1, curr, result);
return result;
} public void combinationSum3(int k, int target, int i, List<Integer> curr, List<List<Integer>> result)
{
if(curr.size() == k && target == 0)
{
result.add(new ArrayList<Integer>(curr));
return;
} for(int j = i; j <= 9; j ++)
{
if(target < j)
{
return ;
}
curr.add(j);
combinationSum3(k, target - j, j+1, curr, result);
curr.remove(curr.size() - 1);
}
}
数字组合问题:Combination,CombinationSum,CombinationSum2,CombinationSum3的更多相关文章
- lintcode:数字组合 II
数字组合 II 给出一组候选数字(C)和目标数字(T),找出C中所有的组合,使组合中数字的和为T.C中每个数字在每个组合中只能使用一次. 注意事项 所有的数字(包括目标数字)均为正整数. 元素组合(a ...
- lintcode:数字组合I
数字组合I 给出一组候选数字(C)和目标数字(T),找到C中所有的组合,使找出的数字和为T.C中的数字可以无限制重复被选取. 例如,给出候选数组[2,3,6,7]和目标数字7,所求的解为: [7], ...
- JAVAWEB项目实现验证码中文、英文、数字组合
验证码基础 一.什么是验证码及它的作用 :验证码为全自动区分计算机和人类的图灵测试的缩写,是一种区分用户是计算机的公共全自动程序,这个问题可以由计算机生成并评判,但是必须只有人类才能解答.可以防止恶意 ...
- tyvj1096 数字组合
描述 在N个数中找出其和为M的若干个数.先读入正整数N(1<N<100)和M(1<M<10000), 再读入N个正数(可以有相同的数字,每个数字均在1000以内), 在这N个数 ...
- OpenJudge 2985数字组合 解析报告/DP
2985:数字组合 总时间限制: 1000ms 内存限制: 65536kB 描述 有n个正整数,找出其中和为t(t也是正整数)的可能的组合方式.如:n=5,5个数分别为1,2,3,4,5,t=5: ...
- noi 2985 数字组合
题目链接: http://noi.openjudge.cn/ch0206/2985/ 2985:数字组合 查看 提交 统计 提问 总时间限制: 1000ms 内存限制: 65536kB 描述 有n个正 ...
- JS生成随机的由字母数字组合的字符串
前言 最近有个需求,是需要生成3-32位长度的字母数字组合的随机字符串,另一个是生成43位随机字符串. 方法一 奇妙的写法 1 Math.random().toString(36).substr( ...
- js随机生成字母数字组合的字符串 随机动画数字
效果描述: 附件中只有一个index.html文件有效 其中包含css以及html两部分内容 纯js生成的几个随机数字 每次都不重复,点击按钮后再次切换 使用方法: 1.将css样式引入到你的网页中 ...
- lintcode:数字组合III
数字组合III 组给出两个整数n和k,返回从1......n中选出的k个数的组合. 您在真实的面试中是否遇到过这个题? Yes 样例 例如 n = 4 且 k = 2 返回的解为: [[2,4],[3 ...
- [TVYJ1096]数字组合
时间: 1000ms / 空间: 131072KiB / Java类名: Main 描述 在N个数中找出其和为M的若干个数.先读入正整数N(1<N<100)和M(1<M<100 ...
随机推荐
- mysql数据库导入到oracle数据库
首先,写一个cmd脚本 xx.cmd sqlldr username/password control=xx.ctl errors=10000000 direct=y 再写一个bat脚本xx.bat ...
- [Algorithms] Topological Sort
Topological sort is an important application of DFS in directed acyclic graphs (DAG). For each edge ...
- json字符串和json对象的转换
http://www.json.org/提供了一个json2.js,这样ie8(兼容模式),ie7和ie6就可以支持JSON对象以及其stringify()和parse()方法: parse用于从一个 ...
- screen命令在freebsd安装和使用
安装 # cd /usr/ports/sysutils/screen # make install clean 使用 # screen //以下^A表示同按“Ctrl + A”键 # ^A c //C ...
- php 问题及原因总结
1.php 加水印时出现问题的原因 :或许某个参数输入错误,导致页面一点反应都没有.
- Learning PHP Design Patterns
Learning PHP Design Patterns CHAPTER 1 Algorithms handle speed of operations, and design patterns ha ...
- Java程序员面试题集(1-50
下面的内容是对网上原有的Java面试题集及答案进行了全面修订之后给出的负责任的题目和答案,原来的题目中有很多重复题目和无价值的题目,还有不少的参考答案也是错误的,修改后的Java面试题集参照了JDK最 ...
- HTTP请求 蜘蛛的 user-agent
百度爬虫 * Baiduspider+(+http://www.baidu.com/search/spider.htm”) google爬虫 * Mozilla/5.0 (compatible; Go ...
- java中集合的扩容
对于Java中的各种集合类,根据底层的具体实现,小结了一下大致有3种扩容的方式: 1.对于以散列表为底层数据结构实现的,(譬如hashset,hashmap,hashtable等),扩容方式为当链表数 ...
- node.js---sails项目开发(1)
1.安装Node.js和npm---这里就做介绍啦! 2.需要全局下安装Sails sudo npm install sails -g 3. 在本地创建一个文件夹 mkdir ~/lsg/sails ...