数字组合问题: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 ...
随机推荐
- Powershell数据处理
1.导出csv文档 Export-Csv D:\ps\xxx.csv -Encoding UTF8 -NoTypeInformation 2.发送mail $from="frommailad ...
- IE数组排序问题的处理
有一哥们在微信开发中,到生成签名这抓狂了一天 最后发现微信调试工具在IE和chrome下对字符的排序竟然不同. 嗯,这个问题引起了我的关注,于是根据微信工具里的对象数组格式,撸了几句代码调试了一下,发 ...
- ORACLE_SID的查找
SID是System IDentifier的缩写,而ORACLE_SID就是Oracle System Identifier的缩写,在Oracle系统中,ORACLE_SID以环境变量的形式出现,在特 ...
- Spring 框架整合JUnit单元测试
// 整合之前 public class Demo{ @Test public void fun(){ // 获取工厂,加载配置文件 ApplicationContext ac = new Class ...
- caffe杂
一.finetune命令: mpirun /home/zhangsuosheng/caffe_mpi/build/tools/caffe train -solver solver.prototxt - ...
- Calico相关资料链接
部署calico的两个yaml文件: kubectl apply -f http://docs.projectcalico.org/v2.3/getting-started/kubernetes/in ...
- 使用 Python 编写 vim 插件
使用 Python 编写 vim 插件 - 技术翻译 - 开源中国社区 code {margin: 0;padding: 0;white-space: pre;border: none;backgro ...
- R 基本函数总结
基本一.数据管理 vector:向量 numeric:数值型向量 logical:逻辑型向量 character:字符型向量 list:列表 data.frame:数据框 c:连接为向量或列表 len ...
- HadoopHA简述
1 概述 在hadoop2.0之前,namenode只有一个,存在单点问题(虽然hadoop1.0有 secondarynamenode,checkpointnode,buckcupnode这些,但是 ...
- python16_day05【迭代器、生成器、模块】
一.列表生成式 1.我现在有个需求,看列表[0, 1, 2, 3, 4, 5, 6, 7, 8, 9],我要求你把列表里的每个值加1,你怎么实现?你可能会想到2种方式 : >>> a ...