生成1~n的全排列

输入正整数n,输出n的全排列。

样例输入1:

3

样例输出1:

1 2 3

1 3 2

2 1 3

2 3 1

3 1 2

3 2 1

分析:

按字典序从小到大的顺序输出所有的排列。

(字典序:两个序列的字典序大小关系等价于从头开始第一个不相同位置处的大小关系)

使用数组a保存排列中的数,集合s代表剩下的数。

则有

方法1:

1.伪代码:

int dfs(a,s,cur){//找到排列中的第cur个数字。

If (s==空) 输出这个排列;

else

取集合s中的元素i;

a[cur]=i  ;//存到a数组中

dfs(a,s,cur+1);

}

s集合可以省掉,直接用a来表示,如果i在a[1]~a[cur-1]中存在,则说明i已经使用,否则说明i在集合s中。

因为要从第一个数字开始找,所以首先调用dfs(1)  //cur=1

源代码:

#include<cstring>

using namespace std;

int a[100],s, n;;

void dfs(int cur){//函数没有返回值,所以类型为void

if (cur==n+1) {

for (int i=1;i<n;i++) cout<<a[i]<<" ";

cout<<a[n]<<endl;

s++;

}

else for (int i=1;i<=n;i++){

int ok=1;

for(int j=1;j<cur;j++)  //因为当前找第cur个数字,所以和前面已经找到的cur-1个数字比较

if(a[j]==i) ok=0;

if (ok){ a[cur]=i ;dfs(cur+1);}

}

}

int main(){

memset(a,0,sizeof(a));

cin>>n;

dfs(1);

cout<<s<<endl;

return 0;

}

思考:

(1)全局变量与局部变量;

比如a数组和变量n,s在main和dfs中都要用到,所以定义为全局变量,cur只在当前调用的函数中使用,所以定义为局部变量。

(2)函数没有返回值时如何处理。

  函数没有返回值时,函数类型为void,可以没有return语句,也可以有,但其后没有表达式

return ;

2.

伪代码:

int dfs(cur){//已经找到cur个数字,准备找下一个。

If (s==空) 输出这个排列;

else

取集合s中的元素i;

a[cur+1]=i  ;//存到a数组中

dfs(cur+1);

}

初始时已经找到了0个数字,所以首先调用dfs(0)

 1 #include<iostream>
 2 #include<cstring>
 3 using namespace std;
 4 int a[100],s=0, n;
 5 void dfs(int cur){//函数没有返回值时类型为void
 6     if (cur==n) {
 7         for (int i=1;i<n;i++) cout<<a[i]<<" ";
 8         cout<<a[n]<<endl;
 9         s++;
10     }
11     else
12          for (int i=1;i<=n;i++){
13               int ok=1;
14               for(int j=1;j<=cur;j++)
15                     if(a[j]==i) ok=0;
16               if (ok){
17                   a[cur+1]=i;
18                   dfs(cur+1);
19             }
20           }
21 }

 1 #include<iostream>
 2 #include<cstring>
 3 using namespace std;
 4 int a[100],s, n;;
 5 void dfs(int cur){
 6     if (cur==n) {
 7         for (int i=1;i<n;i++) cout<<a[i]<<" ";
 8         cout<<a[n]<<endl;
 9         s++;
10     return;
11     }
12      for (int i=1;i<=n;i++){
13           int ok=1;
14           for(int j=1;j<=cur;j++)
15                 if(a[j]==i) ok=0;
16           if (ok){
17               a[cur+1]=i;
18               dfs(cur+1);
19         }
20      }
21 }

时间: 2024-11-02 23:34:19

生成1~n的全排列的相关文章

ZOJ Problem Set - 3861 ( DFS + 子集生成 + 有条件的全排列生成 )

Valid Pattern Lock -------------------------------------------------------------------------------- Time Limit: 2 Seconds      Memory Limit: 65536 KB -------------------------------------------------------------------------------- Pattern lock securi

生成1~n的全排列,按字典序输出

这个题按照书上的解法,输出顺序并不是字典序,所以在网上找到了一个很棒的解法,先写到这里记录下来. #include<iostream> using namespace std; int a[100]; void dfs(int cur,int n)//cur表示目前正在填的数,n表示总共要填的数 { if(cur==n)//递归边界,说明填完了 { for(int i=0;i<n;i++)//一个一个的输出 cout<<a[i]<<" "; c

[全排列]基于逆序列的字典序法的改进

摘要: 字典序法是生成全排列的经典算法.本文在对字典序法进行分析的基础上,提出了一种基于逆序列的改进字典序全排列生成算法.通过与传统的四种全排列生成算法进行对比,本文方法可以大大提高全排列的生成效率.关键词:全排列;字典序;逆序列 基于逆序列的字典序法的改进 code

减一技术应用:生成排列与幂集(Java实现)

减一技术,与二分搜索一样,是一种通用算法设计技术.它是分治法的一种特殊形式,通过建立问题实例P(n) 与问题实例P(n-1)的递推求解关系式而实现:最经典的例子莫过于插入排序了.这里,给出减一技术在生成排列组合方面的应用. (一)  排列问题: 生成自然数 1,2,,,,,n 的所有排列. 算法描述: 使用减一技术,建立自然数12...n的排列与12...n-1的递推关系.假设 P(n-1) 是 自然数 12...n-1的所有排列 p1, p2,..., p(m)的集合,则P(n)通过如下方式得

【codeup】1959: 全排列 及全排列算法详解

题目描述 给定一个由不同的小写字母组成的字符串,输出这个字符串的所有全排列.我们假设对于小写字母有'a' < 'b' < ... < 'y' < 'z',而且给定的字符串中的字母已经按照从小到大的顺序排列. 输入 输入只有一行,是一个由不同的小写字母组成的字符串,已知字符串的长度在1到6之间. 输出 输出这个字符串的所有排列方式,每行一个排列.要求字母序比较小的排列在前面.字母序如下定义:已知S = s1s2...sk , T = t1t2...tk,则S < T 等价于,存

[2017BUAA软工]第一次个人项目 数独的生成与求解

零.Github链接 https://github.com/xxr5566833/sudo 一.PSP表格 PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟) Planning 计划     · Estimate · 估计这个任务需要多少时间 10   Development 开发     · Analysis · 需求分析 (包括学习新技术)  120   · Design Spec · 生成设计文档  60   · Design

LeetCode46 回溯算法求全排列,这次是真全排列

本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是LeetCode的26篇文章,我们来实战一下全排列问题. 在之前的文章当中,我们讲过八皇后.回溯法,也提到了全排列,但是毕竟没有真正写过.今天的LeetCode46题正是让我们生成给定元素的全排列. 题意很简单,只有一句话,给定一个没有重复元素的序列,让我们返回这个序列所有的全排列,并且我们不需要考虑这些排列的顺序. 回溯法 我们在之前的文章当中分析过,全排列问题,可以看成是搜索问题,从而近似成八皇后问题.在八皇后问题当中,我们枚

LeetCode 046 Permutations

题目要求:Permutations(全排列) Given a collection of numbers, return all possible permutations. For example,[1,2,3] have the following permutations:[1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], and [3,2,1]. 分析: 参考网址:http://www.cnblogs.com/panda_lin/archive/20

ZOJ Problem Set - 3861 Valid Pattern Lock(dfs)

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3861 这道题当时没做出来,后来经过队友提醒才做出来. 3*3的九宫格,给你其中n个点按下面要求连起来: 1. 给你的n个点都要激活(至少经过一次) 2. 如果点A,B相连后要经过另一个点C,则C在序列中的位置必须在A,B之前 如 1 7 4是不合法的 3.线段相交是没关系的,如 7 6 9 4 我是直接生成n个数的全排列,然后在所有排列里面去掉不合法的. 1 #inclu