求全排列
来源:互联网 发布:微信朋友圈 淘宝链接 编辑:程序博客网 时间:2024/05/22 12:26
Tags: 算法
1. 描述
给定一个数组a, 下标从0开始,a中的元素不重复, 求a中元素的全排列。
2. 解法
解法一:
该算法基于公式:
#include<iostream>using namespace std;void doPerm(int a[], int start, int n) { if (start == n) { for (int i = 0; i < n; ++i) cout<<a[i]<<" "; cout<<endl; } else { for (int j = start; j < n; ++j) { swap(a[start], a[j]); doPerm(a, start + 1, n); swap(a[start], a[j]); } }}inline void perm(int a[], int n) { doPerm1(a, 0, n);}
n等于3时,算法的求解过程可用下图表示,其中同一父节点下的一层代表一轮for循环(代码第11~15行)的执行。
不考虑输出,其时间复杂度主要在于perm的调用次数或第11行for循环的执行次数,即图中所有结点的次数为 1 + n + n * (n - 1) + … + n * (n - 1) * (n - 2) * … * 1 + n * (n - 1) * (n - 2) * … * 1, 即复杂度为O(n!)。
解法二:
穷举待输出集合b的每一个位置i,该位置未填元素(b[i]等于0),向一个集合中补给一个元素,此例子为先选a集合中下标大的元素,当集合b需要的元素个数为0时,输出该集合。
#include<cstring>#include<iostream>using namespace std;void doPerm(int a[], int n, int cur, int b[]) { if (cur == 0) { for (int i = 0; i < n; ++i) cout<<b[i]<<" "; cout<<endl; } else { for (int j = 0; j < n; ++j) { if (b[j] == 0) { b[j] = a[cur - 1]; doPerm(a, n, cur - 1, b); b[j] = 0; } } }}inline void perm(int a[], int n) { int* b = new int[n]; memset(b, 0, n * sizeof(int)); doPerm(a, n, n, b);}
求解过程如下图所示, 由于每次向b中添加一个元素都会穷举一次,所以忽略输出的话,算法执行消耗主要在第12行for循环的执行次数上,n等于3时,算法的求解过程可用下图表示,其中同一父节点下的一层代表一轮for循环(代码第11~15行)的执行。
不考虑输出,其时间复杂度主要在于perm的调用次数或第11行for循环的执行次数,即为 1 * n + n + n * (n - 1) * n + … + n * (n - 1) * (n - 2) * … * 1 * n, 其执行次数显然多余解法一的执行次数。
0 0
- 求全排列
- 求全排列
- 求全排列
- 求全排列
- 求全排列
- 求全排列
- 求全排列
- 求全排列
- 求全排列
- 递归求全排列
- 递归求全排列
- 递归求全排列
- 回溯法求全排列
- 递归方法求全排列
- 求全排列问题
- DFS求全排列
- 递归求全排列
- 求全排列和组合
- JAVA设计模式之单例模式
- Redis源码剖析和注释(十)--- 列表键命令实现(t_list)
- 我的编程规范
- LaTex特殊符号
- Add Two Numbers
- 求全排列
- SVN管理命令
- Spring之如何导入包到已有工程中
- linux下安装numpy
- Lecture 20 Parallel Algorithms I
- 前端组件练习
- 一步一步学springboot 一
- jsDOM元素创建:
- 编一个程序,将两个字符串s1和s2比较,返回差值,即实现strcmp函数功能