数字组合问题: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 ...
随机推荐
- 爬虫实战【11】Python获取豆瓣热门电影信息
之前我们从猫眼获取过电影信息,而且利用分析ajax技术,获取过今日头条的街拍图片. 今天我们在豆瓣上获取一些热门电影的信息. 页面分析 首先,我们先来看一下豆瓣里面选电影的页面,我们默认选择热门电影, ...
- python之MongoDB学习
import pymongo as pm # 获取连接 client = pm.MongoClient('localhost', 27017) # 端口号是数值型 # 连接数据库 db = clien ...
- Centos6.5下Samba服务器的安装和配置
1.安装samba服务 # yum install samba samba-client samba-swat 2.安装包说明 samba-3.6.23-43.el6_9.x86_64----> ...
- 巨蟒python全栈开发-第6天 is&==
1.小数据池 2.id 3.decode和encode 小数据池 #小数据池:不要死磕就行#python为了简化,搞出来的一个东西 ID (1)# id()函数可以帮我们查看一个变量的内存地址# a= ...
- 第四课(2)——mysql配置参数讲解
*****************general***************** user 启动mysql domain的用户 port 数据库端口号 socket 数据库socket文件的路径 p ...
- "AppServer"--->UDP--->"LogWriteServer"
w 是否应该将日志的“写”独立至局域网的一台或一群专门服务于“写日志”的服务器?这样让“app服务器”专职地处理用户的请求,而不必因为“写日志甚至异步分析日志”来降低用户体验? Spencer老师 其 ...
- python的socket的学习
一.Socket相关知识 1.socket是什么: socket是应用层与TCP/IP协议族通信的中间软件抽象层,他是一组接口.在设计模式中,Socket其实就是一个门面模式. 它把复杂的TCP/IP ...
- Java中堆内存与栈内存分配浅析
Java把内存划分成两种:一种是栈内存,另一种是堆内存.在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配,当在一段代码块定义一个变量时,Java就在栈中为这个变量分配内存空间, ...
- plotly绘制直方图示例
计算数值出现的次数“ import cufflinks as cf cf.go_offline() import numpy as np import pandas as pd set_slippag ...
- Django框架视图类
类视图 在写视图的时候,Django除了使用函数作为视图,也可以使用类作为视图.使用类视图可以使用类的一些特性,比如继承等. View django.views.generic.base.View是主 ...