所谓排列,是指从给定的元素序列中依次取出元素,需要考虑取出顺序。比如,取出元素3, 5,因取出顺序的不同,则形成的序列{3, 5}与{5, 3}是不同的排列序列。对于长度为n的元素序列取出k个元素,则共有A(n, k)种取法。所谓组合,也是从元素序列中依次取出元素,与排列不同的是不需要考虑取出顺序;因此其取法数为C(n, k)。

LeetCode有两个问题分属于组合、排列:77. Combinations46. Permutations

组合

要求给出对于序列1~n 的取出k个元素的各种取法。采用DFS模拟组合时,可看做节点i与节点j(j = i+1, … , n)都相连接,然后DFS遍历整张有向图,代码实现如下:

public List<List<Integer>> combine(int n, int k) {
List<List<Integer>> result = new ArrayList<>();
if (n <= 0 || n < k) {
return result;
}
List<Integer> tmp = new ArrayList<>();
dfs(n, k, 1, tmp, result);
return result;
} // DFS for combination
private void dfs(int n, int k, int start,
List<Integer> tmp, List<List<Integer>> result) {
if (tmp.size() == k) {
result.add(new ArrayList<Integer>(tmp));
return;
}
for (int i = start; i <= n; i++) {
tmp.add(i);
dfs(n, k, i + 1, tmp, result);
tmp.remove(tmp.size() - 1); // remove the last
}
}

排列

DFS实现排列与组合相类似,唯一不同之处在于,节点i与其他所有节点都连接。因此,所构造的图是一个完全连通图。DFS实现排列如下:

public List<List<Integer>> permute(int[] nums) {
List<List<Integer>> result = new ArrayList<>();
if (nums.length == 0) {
return result;
}
List<Integer> tmp = new ArrayList<>();
dfs(nums, tmp, result);
return result;
} // DFS for permutation
private void dfs(int[] nums, List<Integer> tmp,
List<List<Integer>> result) {
int n = nums.length;
if (tmp.size() == n) {
result.add(new ArrayList<>(tmp));
return;
}
for (int i = 0; i < n; i++) {
// nums[i] has not been visited
if (!tmp.contains(nums[i])) {
tmp.add(nums[i]);
dfs(nums, tmp, result);
tmp.remove(tmp.size() - 1);
}
}
}

上述代码中,可以用一个visit数组来标记节点是否被访问,这样优化将contains的时间复杂度从\(O(n)\)优化到\(O(1)\)。

DFS实现排列组合的更多相关文章

  1. Codeforces 991E. Bus Number (DFS+排列组合)

    解题思路 将每个数字出现的次数存在一个数组num[]中(与顺序无关). 将出现过的数字i从1到num[i]遍历.(i from 0 to 9) 得到要使用的数字次数数组a[]. 对于每一种a使用排列组 ...

  2. [leetcode] 题型整理之排列组合

    一般用dfs来做 最简单的一种: 17. Letter Combinations of a Phone Number Given a digit string, return all possible ...

  3. Day4:T3搜索 T4数学题排列组合

    T3:搜索 很出名的题吧,费解的开关 同T2一样也是一题很考思考的 附上题解再解释吧: 对于每个状态,算法只需要枚举第一行改变哪些灯的状态,只要第一行的状态固定了,接下来的状态改变方法都是唯一的:每一 ...

  4. 2017ACM暑期多校联合训练 - Team 1 1006 HDU 6038 Function (排列组合)

    题目链接 Problem Description You are given a permutation a from 0 to n−1 and a permutation b from 0 to m ...

  5. LeetCode OJ:Combinations (排列组合)

    Given two integers n and k, return all possible combinations of k numbers out of 1 ... n. For exampl ...

  6. 学习sql中的排列组合,在园子里搜着看于是。。。

    学习sql中的排列组合,在园子里搜着看,看到篇文章,于是自己(新手)用了最最原始的sql去写出来: --需求----B, C, F, M and S住在一座房子的不同楼层.--B 不住顶层.C 不住底 ...

  7. .NET平台开源项目速览(11)KwCombinatorics排列组合使用案例(1)

    今年上半年,我在KwCombinatorics系列文章中,重点介绍了KwCombinatorics组件的使用情况,其实这个组件我5年前就开始用了,非常方便,麻雀虽小五脏俱全.所以一直非常喜欢,才写了几 ...

  8. 【原创】开源.NET排列组合组件KwCombinatorics使用(三)——笛卡尔积组合

           本博客所有文章分类的总目录:本博客博文总目录-实时更新 本博客其他.NET开源项目文章目录:[目录]本博客其他.NET开源项目文章目录 KwCombinatorics组件文章目录: 1. ...

  9. 【原创】开源.NET排列组合组件KwCombinatorics使用(二)——排列生成

           本博客所有文章分类的总目录:本博客博文总目录-实时更新 本博客其他.NET开源项目文章目录:[目录]本博客其他.NET开源项目文章目录 KwCombinatorics组件文章目录: 1. ...

随机推荐

  1. 【C#学习笔记之一】C#中的关键字

    C#中的关键字 关键字是对编译器具有特殊意义的预定义保留标识符.它们不能在程序中用作标识符,除非它们有一个 @ 前缀.例如,@if 是有效的标识符,但 if 不是,因为 if 是关键字. 下面是列出的 ...

  2. HUST 1555 A Math Homework

    1555 - A Math Homework 时间限制:1秒 内存限制:128兆 338 次提交 131 次通过 题目描述     QKL is a poor and busy guy, and he ...

  3. UVAlive 3708 Graveyard(最优化问题)

    题目描述: 在周长10000的圆上,初始等距的放置着n个雕塑,现在新加入m个雕塑,要使得这n+m个雕塑仍然等距,问原来n个雕塑要移动的距离总和的最小值. 原题地址: http://acm.hust.e ...

  4. BZOJ 2463: [中山市选2009]谁能赢呢?(新生必做的水题)

    2463: [中山市选2009]谁能赢呢? Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2372  Solved: 1750[Submit][Sta ...

  5. [bzoj1997][Hnoi2010]Planar(2-sat||括号序列)

    开始填连通分量的大坑了= = 然后平面图有个性质m<=3*n-6..... 由平面图的欧拉定理n-m+r=2(r为平面图的面的个数),在极大平面图的情况可以代入得到m=3*n-6. 网上的证明( ...

  6. 关于python 2.7要求输出汉字问题

    对于python 2.7,使用print u'好好学习'会出现异常.可用以下作为汉字输出,获取数据(字符串)时,用unicode(str, "utf8")生成unicode对象 p ...

  7. Springboot-shiro-redis实现登录认证和权限管理

    Springboot-shiro-redis实现登录认证和权限管理 在学习之前: 首先进行一下Apache Shiro和Shiro比较: Apache Shiro是一个功能强大.灵活的,开源的安全框架 ...

  8. Winform 控件的入门级使用(一)

    开始总结一下控件的基本用法,方便以后查阅. 一.Label Label 的使用频率很高,基本上也没有什么难度. #region Winform //label label.Text = "这 ...

  9. Tomcat源码调试环境搭建

    我们一般都是为了解决某个问题,才去看源码的.Java体系就是这点好处,源码唾手可得.遇到问题,最后的解决方法总是可以从源码中找到. 参考了网上的文章,过程整理如下: 1. 下载和导入 官网下载编译好的 ...

  10. C++ 初始化列表(转)

    转载自:http://www.cnblogs.com/graphics/archive/2010/07/04/1770900.html 何谓初始化列表 与其他函数不同,构造函数除了有名字,参数列表和函 ...