排列和组合 Permutation and Combination
排列和组合 Permutation and Combination ---- Based on DFS and Backtracking
- Basic Concepts
- Permutation
- Combination
- Permutation
- Permutation --- Leetcode 46
- String Permutation --- Lintcode 10
- Combination
- Subsets (without duplicates) --- Leetcode 78
- Subsets II (with duplicates) --- Leetcode 90
- Summary
- Time Complexity of Combination and Permutation
Basic Concepts
Permutation
- A permutation of n distinct objects is an arrangment ( or ordering) of all n objects.
- Denoted as P(n)
- P(n) = n !
Example 1:
Suppose 10 students are sitting for a class picture. How many ways are there to arrange 10 students.
Answer: 10 * 9 *… * 2 * 1 = 10!
- An r-permutation n distinct objects is an arrangment (or ording) of r of the n objects.
- Denoted as P(n,r)
- P(n, r) = n! / (n-r)!
Example 1:
Suppose 10 students are sitting for a class picture. How many ways are there to arrange the row of 3 students.
Answer: 10 * 9 * 8 = 720
Combination
- An r-combination of n distinct objects is a selection (order doesn’t matter) of r of n objects. (Alson known as Sets)
- Denoted as C(n, r)
- C(n, r) = {n !} / {(n-r) ! r!}
Example 1:
How many 5 letters subsets can be made from 26 English letter.
Answer C(26, 5)Example 2:
Calculate all subsets of number 12345
Answer = C(5,5) + C(5,4) + C(5,3) + C(5,2) + C(5,1) + C(5,0) = 25
Because for each digit, it has two options: choose or not choose
Therefore: 2 * 2 * 2 * 2 * 2
Permutation
Permutation — Leetcode 46
class Solution {public List<List<Integer>> permute(int[] nums) {List<List<Integer>> output = new ArrayList<List<Integer>>();List<Integer> tempList = new ArrayList<Integer>();return permutation(tempList, nums, output);}public List<List<Integer>> permutation(List<Integer> tempList, int [] nums, List<List<Integer>> output) {//output长度和数组长度一样,代表本次排列完成,可以返回if (tempList.size() == nums.length) {output.add(new ArrayList(tempList));//output.add(tempList); 就不可以, 因为加入的是tempList的地址,所以之前加入的tempList会因为后面对tempList的改变而改变return output;}//对数组中每个元素进行遍历for(int i = 0; i < nums.length; i++) {if (!tempList.contains(nums[i])) { //如果目前记录的output里有num[i],则跳过此次循环(防止重复)tempList.add(nums[i]); //把当前元素加入outputpermutation(tempList, nums, output); //进行下一次循环, 完成dfstempList.remove(tempList.size()-1); //回到本层之后,删除之前num[i],完成回溯}}return output;}
}
String Permutation — Lintcode 10
public class Solution {/*** @param str: A string* @return: all permutations*/public List<String> stringPermutation2(String str) {str = sortString(str);List<String> ans = new ArrayList<>();StringBuilder temp = new StringBuilder();boolean [] visited = new boolean[str.length()];dfs(visited, str, temp, ans);return ans;}public void dfs(boolean [] visited, String str, StringBuilder temp, List<String> ans) {if (temp.length() == str.length()) {//不能用注释掉的方式去重,会超时/* if (!ans.contains(temp.toString())) {ans.add(temp.toString());}*/ ans.add(temp.toString());return;}for(int i = 0; i < str.length(); i++) {if (visited[i]) {continue;}//这里if的作用是去重: 不同位置的同样的字符,必须按照顺序用// a' a'' b// a' a'' b ok// a'' a' b not okif (i > 0 && str.charAt(i) == str.charAt(i-1) && !visited[i-1]) {continue;}temp.append(str.charAt(i));visited[i] = true;dfs(visited, str, temp, ans);visited[i] = false;temp = temp.deleteCharAt(temp.length()-1);}}public String sortString(String str) {char [] charArray = str.toCharArray();Arrays.sort(charArray);str = new String(charArray);return str;}
}
Combination
Subsets (without duplicates) — Leetcode 78
class Solution {public List<List<Integer>> subsets(int[] nums) {List<List<Integer>> ans = new ArrayList<>();List<Integer> temp = new ArrayList<>();if (nums.length == 0) {ans.add(new ArrayList<Integer>(temp));return ans;}dfs(ans, temp, nums, 0);return ans;}public void dfs(List<List<Integer>> ans, List<Integer> temp, int [] nums, int startIndex) {//将集合加入ans//用startIndex防止重复//take N to copy to ans listans.add(new ArrayList<Integer>(temp));for (int i = startIndex; i < nums.length; i++) { temp.add(nums[i]);dfs(ans, temp, nums, i + 1);//backtrackingtemp.remove(temp.size()-1);}}
}
Subsets II (with duplicates) — Leetcode 90
class Solution {public List<List<Integer>> subsetsWithDup(int[] nums) {Arrays.sort(nums); //must sort in order to skip all the duplicate subsetsList<List<Integer>> ans = new ArrayList<>();List<Integer> temp = new ArrayList<>();dfs(nums, ans, temp, 0);return ans;}public void dfs(int [] nums, List<List<Integer>> ans, List<Integer> temp, int startIndex) {ans.add(new ArrayList<Integer>(temp));for(int i = startIndex; i < nums.length; i++) {// skip all the duplicate//if the current number is same as previous one, then skip//Exception: if the previous number is the startIndex ( i > startIndex )//Example: a b' b'' b''' d//startIndex: 1//a b' b'' d ok//a b' b''' d not okif ( i > startIndex && nums[i-1] == nums[i]) {continue;}temp.add(nums[i]);dfs(nums, ans, temp, i + 1);temp.remove(temp.size() - 1); //backtracking}}
}
Summary
- Examples shown above are template for solving all combination and permutation problems.
- Combination needs startIndex, Permutations doesn’t need startIndex
- For handling duplicated elements in input:
- Sort Input
- Add following code in for loop
Combination:
if ( i > startIndex && nums[i-1] == nums[i]) { continue; }
Permutation:
if (i > 0 && str.charAt(i) == str.charAt(i-1) && !visited[i-1]) { continue; }
Time Complexity of Combination and Permutation
- Combination — Subsets problem (Leetcode 78)
2n * n : A total of 2n possibilities and each possibility takes N to copy to the ans list
Why 2n: for example, for string 12345, each number has an option of choose or not choose, therefore 2n- Permutation — Permutation problem (Leetcode 46)
n! * n: A total of n! possibilities and each possibility takes N to copy to the ans list
General formula for DFS:
Number of possibilities * Time to create each possibility
排列和组合 Permutation and Combination相关推荐
- Permutation test(排列(组合)检验)
2019独角兽企业重金招聘Python工程师标准>>> 对Permutation test 的首次描述可追溯到上个世纪30年代, Fisher( 1935) 和Pitman( 193 ...
- 多重集合的排列和组合问题
多重集合的排列和组合问题 标签: permutationn2c扩展 2012-04-17 16:18 5671人阅读 评论(0) 收藏 举报 分类: 算法(12) 版权声明:本文为博主原创文章,未 ...
- 深入浅出统计学 第六章 排列与组合
内容简介 本章内容主要介绍了两个基本概念,排序与组合 其中组合是之后计算二项分布的预备知识 对于计算而言,重点在于理解其所适应的不同情况,并记忆公式. 两者区别(P261): 1. 排列与顺序有关 2 ...
- 排列与组合的Java递归实现 (参考)
我们在笔试面试过程中经常会遇到关于排列与组合的问题,其实这些可以通过递归简单的实现,看下面两个例子: (1)关于字符串排列的问题 输入一个字符串,打印出该字符串中字符的所有排列.例如输入字符串abc, ...
- 排列公式和组合公式_排列与组合:排列公式与组合公式之间有什么区别?
排列公式和组合公式 Here's the short version. 这是简短的版本. Let's take ringing bells in a church as an example. 让我们 ...
- java排列和组合算法
package com.louisgeek.price;/*** 排列和组合算法* @author Administrator**/ public class CaseTest {public sta ...
- 通用的非递归排列和组合算法[附源码]
动机 Apache Math包中有很多关分布的算法,但是没有找到排列组合相关的算法.索性自己写一个.排列组合可以分两个算法: 组合算法,就是在一个数组中取出m(小于等于数组的长度 n)个对象,有多少中 ...
- 回溯算法团灭子集、排列、组合问题
回溯算法团灭子集.排列.组合问题 一.子集 给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集). 说明:解集不能包含重复的子集. 示例: 输入: nums = [1,2,3] ...
- 数学基础知识-排列与组合
文章目录 前言 一.分步乘法原理 1.定义 2.举例 二.排列 1.定义 2.计算公式 3.举例分析 4.公式推导过程 三.组合 1.定义 2.计算公式 3.举例分析 4.其他一些规定和转换 总结 前 ...
- java 实现组合_用Java实现排列、组合算法
组合个数的计算公式如下: 那么,计算排列或组合的数量,通过上面的公式就很容易就算出来了,其Java的实现如下: /** * 计算阶乘数,即n! = n * (n-1) * ... * 2 * 1 * ...
最新文章
- 橡皮筋进度条ElasticProgressBar
- 网页效果图设计之色彩索引
- csapp:无符号数可能造成的程序bug
- 解决:Cannot resolve plugin org.apache.maven.plugins:maven-compiler-plugin:2.3.2问题
- learning rate四种改变方式
- 后宫佳丽三千,假如古代皇帝也懂负载均衡算法...
- java queue 最大值_[剑指offer题解]队列的最大值/滑动窗口的最大值
- asp.net单一登录
- conn.execute
- element动态form实现
- BZOJ 1070: [SCOI2007]修车
- JS查漏补缺(自用版)
- 力扣题目——53. 最大子序和
- 电脑硬件故障排除经验
- php 展示微信图片尺寸,微信公众平台图片最大尺寸
- 启动“附近的人”功能,你有兴趣吗?
- 2019~2020数字货币领域发展趋势报告
- 视频教程-【吴刚】电商活动站设计初级入门标准视频教程-UI
- ubuntu18.04 littlevgl运行环境搭建
- 视频里面的音频怎么提取成mp3?