递归求全排列的学习与理解
递归求全排列
全排列:
从n个不同元素中任取m(m≤n)个元素,按照一定的顺序排列起来,叫做从n个不同元素中取出m个元素的一个排列。当m=n时所有的排列情况叫全排列。
例题:
输出自然数 1 到n所有不重复的排列,即 n 的全排列,要求所产生的任一数字序列中不允许出现重复的数字。
比如:求1~3的全排列
由中学的知识便知共有 3! =3 x 2 x 1=6种 排列,即123,132,213,231,312,321
那么该怎么用代码求出来呢?像我这种萌新,一开始想到的当然是用for循环,但是求1~3的全排列可以用3个for循环,那么当要求1-n(n为用户输入),for循环的个数便确定不了了。
于是,便需要用递归了。看了很多大佬的代码都看不太懂,最后还是得自己推一遍才懂,还是得多动手啊!
代码如下:
#include<iostream>
using namespace std;int a[20],flag[20]; //a用来装产生的排列 flag为标记数组
//虽然计算机可以算较大的数排列,但是越大时间越长,还会产生栈溢出的情况,这里就只开了20个空间的数组
int n; //n : 产生n个数的全排列void DFS(int step) //step可以理解为一个排列的第几个数字
{if(step==n+1) //当step达到要排列的个数时,就输出{for(int i=1;i<=n;i++)printf("%5d",a[i]); //每个数字空5格输出cout<<endl;}for(int i=1;i<=n;i++){if(flag[i]==0){a[step]=i; //step为第几个数字 flag[i]=1;DFS(step+1);flag[i]=0; //回溯}}
}int main()
{cin >> n;DFS(1); //从第一个数字开始return 0;
}
调用DFS函数递归图解:
下面举例求1~4的全排列,函数初始值传入1
以此类推,数组a,flag被赋值为
数组a:
下标 | 值 |
---|---|
0 | 0 |
1 | 1 |
2 | 2 |
3 | 3 |
4 | 4 |
数组flag:
下标 | 值 |
---|---|
0 | 0 |
1 | 1 |
2 | 1 |
3 | 1 |
4 | 1 |
当DFS(4)执行到DFS(4+1)即DFS(5)时,进入函数出口,满足if(5=4+1),DFS(5)退出,开始回溯,图解如下:
每次排列完4个就输出一次。
总而言之,整个过程就是从数组前面往后排列数字,然后不断从后面开始向前面更新。
学习总结
理解该过程要结合栈的递归,搞清楚各个步骤,尤其是一个函数结束返回上一层以及回溯的过程。而要写出这种递归代码还是需要多做题啊!
递归求全排列的学习与理解相关推荐
- Java递归求全排列详解
Java递归求全排列详解 推荐博客: 博客园Java全排列递归算法,结尾的解释很形象了 csdn的大佬写的,和我下面的代码思路基本一致 全排列的递归思想解释: 全排列的数学定义就不再过多解释,考虑递归 ...
- 递归 求全排列与全组合
我在百度,触宝面试的时候,他们都问到了递归. 递归是一个很有意思的问题,其中的经典问题有汉诺塔,fibonacci 数列问题.汉诺塔是比较难的问题,fibonacci 是比较简单的问题. 触宝面试的时 ...
- 不使用递归求全排列和组合数
同学遇到的面试问题,大意是M台机器放在N个房间,不使用递归求打印所有情况 解题思路:情况共计N**M种.开始想将所有情况放入数组,填充好数组再逐个打印.随后发现按照填充的思路,不使用大数组也可以实现. ...
- 三种求全排列方式之比较
一共有三种求全排列的方式: 第一种就是只适合用于非可重集的DFS实现 第二种就是可以用于可重集上的刘汝佳书上的代码 第三种就是STL中的next--permutation 在对这三种方式做了比较之后发 ...
- 《C++应用程序性能优化::第二章C++语言特性的性能分析》学习和理解
<C++应用程序性能优化::第二章C++语言特性的性能分析>学习和理解 说明:<C++应用程序性能优化> 作者:冯宏华等 2007年版.最近出了新版,看了目录,在前面增加了一章 ...
- 蓝桥杯笔记:(给的元素不重复)求全排列(排列不可重复,排列可重复)
1.各个元素不重复 abc,acb,....... 用next_permutataion()求全排列 #include<iostream> #include<algorithm> ...
- C++ STL求全排列和组合
C++11 STL内置了求全排列的模板函数next_permutation和prev_permutation,属于<algorithm>头文件和std命名空间,使用非常方便.例如: vec ...
- 【汉诺塔】C语言递归解法,深层次地带你理解汉诺塔公式
目录 汉诺塔公式 汉诺塔问题在数学层面的公式: C语言递归公式 两层汉诺塔 三层汉诺塔 递归问题可谓是学习C语言以来的第一个拦路虎,而汉诺塔问题更是递归中对新手很不友好的一道经典题,我们接下来从公式角 ...
- 关于ATIS以及基于注意力机制的递归神经网络模型 的学习记录
关于ATIS以及基于注意力机制的递归神经网络模型 的学习记录 此为本人学习的类笔记,主要内容为借助Google翻译机译的论文WHAT IS LEFT TO BE UNDERSTOOD IN ATIS? ...
最新文章
- git rollback代码都没了_Git使用总结
- 知乎:什么时候你是产品经理,而不是产品助理?
- 关于Android SDK工具Lint的误报分析
- 1054 The Dominant Color (20 分)_12行代码AC
- php mysql倒计时_php 倒计时程序
- BZOJ 1597 [Usaco2008 Mar] 土地购买
- markDown用这一招实现图片并排显示
- 《C语言及程序设计》实践参考——间隔选职工
- 论文赏析[NAACL19]无监督循环神经网络文法 (URNNG)
- JAVA 事务回滚方法调用非事务回滚方法
- 他靠写程序封神,买不起操作系统,就动手写一个!曾拒绝乔布斯的offer
- Java实现IP库归属地查询
- 安卓手机软件开发_这款安卓神器,让你下片更轻松!千万别滥用
- 【算法】全排列的四种思路
- 运放基本结构及频响(一)
- 数据结构——实现双栈操作
- 正则表达式验证包含0的正正整数
- Python使用Matplotlib绘制三维折线图(进阶篇)
- uefi多linux系统启动盘,【XORBOOT Uefi(多系统启动工具)和好用U盘启动盘制作工具哪个好用】XORBOOT Uefi(多系统启动工具)和好用U盘启动盘制作工具对比-ZOL下载...
- 遇到的一些不错的Java极客程序