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的更多相关文章

  1. lintcode:数字组合 II

    数字组合 II 给出一组候选数字(C)和目标数字(T),找出C中所有的组合,使组合中数字的和为T.C中每个数字在每个组合中只能使用一次. 注意事项 所有的数字(包括目标数字)均为正整数. 元素组合(a ...

  2. lintcode:数字组合I

    数字组合I 给出一组候选数字(C)和目标数字(T),找到C中所有的组合,使找出的数字和为T.C中的数字可以无限制重复被选取. 例如,给出候选数组[2,3,6,7]和目标数字7,所求的解为: [7], ...

  3. JAVAWEB项目实现验证码中文、英文、数字组合

    验证码基础 一.什么是验证码及它的作用 :验证码为全自动区分计算机和人类的图灵测试的缩写,是一种区分用户是计算机的公共全自动程序,这个问题可以由计算机生成并评判,但是必须只有人类才能解答.可以防止恶意 ...

  4. tyvj1096 数字组合

    描述 在N个数中找出其和为M的若干个数.先读入正整数N(1<N<100)和M(1<M<10000), 再读入N个正数(可以有相同的数字,每个数字均在1000以内), 在这N个数 ...

  5. OpenJudge 2985数字组合 解析报告/DP

    2985:数字组合 总时间限制:  1000ms 内存限制:  65536kB 描述 有n个正整数,找出其中和为t(t也是正整数)的可能的组合方式.如:n=5,5个数分别为1,2,3,4,5,t=5: ...

  6. noi 2985 数字组合

    题目链接: http://noi.openjudge.cn/ch0206/2985/ 2985:数字组合 查看 提交 统计 提问 总时间限制: 1000ms 内存限制: 65536kB 描述 有n个正 ...

  7. JS生成随机的由字母数字组合的字符串

    前言 最近有个需求,是需要生成3-32位长度的字母数字组合的随机字符串,另一个是生成43位随机字符串. 方法一 奇妙的写法   1 Math.random().toString(36).substr( ...

  8. js随机生成字母数字组合的字符串 随机动画数字

    效果描述: 附件中只有一个index.html文件有效 其中包含css以及html两部分内容 纯js生成的几个随机数字 每次都不重复,点击按钮后再次切换 使用方法: 1.将css样式引入到你的网页中 ...

  9. lintcode:数字组合III

    数字组合III 组给出两个整数n和k,返回从1......n中选出的k个数的组合. 您在真实的面试中是否遇到过这个题? Yes 样例 例如 n = 4 且 k = 2 返回的解为: [[2,4],[3 ...

  10. [TVYJ1096]数字组合

    时间: 1000ms / 空间: 131072KiB / Java类名: Main 描述 在N个数中找出其和为M的若干个数.先读入正整数N(1<N<100)和M(1<M<100 ...

随机推荐

  1. 选项卡jQuery(ele).each()

    $("li").each(index){    $(this).mouseover(fucntion(){           $("div.contentin" ...

  2. pt-online-schema-change线上DDL注意事项

    在使用pt-online-schema-change做线上DDL的时候对于数据量比较小的表问题不大,但是对于数据量比较大的表(比如:单表2亿数据)访问量较大的时候就有可能出现异常, 原本使用pt-on ...

  3. Kubernetes网络框架

    // cmd/kubelet/app/server.go -1.func UnsecuredKubeletDeps(s *options.KubeletServer) (*kubelet.Kubele ...

  4. 0407-服务注册与发现-Eureka深入理解-元数据、高可用HA

    一.Eureka元数据 参看地址:https://cloud.spring.io/spring-cloud-static/Edgware.SR3/single/spring-cloud.html#_e ...

  5. 让你的代码量减少3倍!使用kotlin开发Android

    (一) 创建Kotlin工程 (二) –秘笈!扩展函数 (三) 缩短五倍的Java Bean 本项目使用的代码地址

  6. sqlite时间段查询

    同样的SQL语句,查不出数据来 select * from table1 where t1>='2017-6-1' and t1<='2017-6-5' 改成 select * from ...

  7. jsp创建cookie

    <jsp:include flush="true" page="header.jsp" /> <script type="text/ ...

  8. HTML中的SEO和HTML语义化

    SEO 1) <title>网站SEO标题</title>, 百度搜索出来的记录, 其标题基本就提取至网站的title, 标签, 因此标题起的好, 不论对点击率还是SEO都至关 ...

  9. go——接口(二)

    多态是指代码可以根据类型的具体实现采取不同行为的能力. 如果一个类型实现了某个接口,所有使用这个接口的地方,都可以支持这种类型的值. 标准库里有很好的例子,如io包里实现的流式处理接口. io包提供了 ...

  10. responseEntity 实现文件下载

    @RequestMapping("/testResponseEntity") public ResponseEntity<byte[]> testResponseEnt ...