全排列算法实现

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/summerxiachen/article/details/60579623

1.全排列的定义和公式:

从n个数中选取m(m<=n)个数按照一定的顺序进行排成一个列,叫作从n个元素中取m个元素的一个排列。由排列的定义,显然不同的顺序是一个不同的排列。从n个元素中取m个元素的所有排列的个数,称为排列数。从n个元素取出n个元素的一个排列,称为一个全排列。全排列的排列数公式为n!,通过乘法原理可以得到。

2.时间复杂度:

n个数(字符、对象)的全排列一共有n!种,所以全排列算法至少时间O(n!)O(n!) 的。如果要对全排列进行输出,那么输出的时间要O(nn!)O(n∗n!) ,因为每一个排列都有n个数据。所以实际上,全排列算法对大型的数据是无法处理的,而一般情况下也不会要求我们去遍历一个大型数据的全排列。

3.列出全排列的初始思想:

解决一个算法问题,我比较习惯于从基本的想法做起,我们先回顾一下我们自己是如何写一组数的全排列的:1,3,5,9(为了方便,下面我都用数进行全排列而不是字符)。
【1,3,5,9】(第一个)
首先保持第一个不变,对【3,5,9】进行全排列。
同样地,我们先保持3不变,对【5,9】进行全排列。
保持5不变,对9对进行全排列,由于9只有一个,它的排列只有一种:9。
故排列为【1,3,5,9】
接下来5不能以5打头了,5,9相互交换,得到
【1,3,9,5】
此时5,9的情况都写完了,不能以3打头了,得到

1,5,3,9
1,5,9,3
1,9,3,5
1,9,5,3
  • 1
  • 2
  • 3
  • 4

这样,我们就得到了1开头的所有排列,这是我们一般的排列数生成的过程。再接着是以3、5、9打头,得到全排列。

我们现在做这样的一个假设,假设给定的一些序列中第一位都不相同,那么就可以认定说这些序列一定不是同一个序列,这是一个很显然的问题。有了上面的这一条结论,我们就可以同理得到如果在第一位相同,可是第二位不同,那么在这些序列中也一定都不是同一个序列。
那么,这个问题可以这样来看。对

T=T=【 x1,x1, x2,x3,x4,x5,........xn1,xnx2,x3,x4,x5,........xn−1,xn】

我们获得了在第一个位置上的所有情况之后(注:是所有的情况),对每一种情况,抽去序列TT 中的第一个位置,那么对于剩下的序列可以看成是一个全新的序列

T1=x2,x3,x4,x5,........xn1,xnT1=【x2,x3,x4,x5,........xn−1,xn】

序列T1T1 可以认为是与之前的序列毫无关联了。同样的,我们可以对这个T1T1 进行与TT 相同的操作,直到TT 中只一个元素为止。这样我们就获得了所有的可能性。所以很显然,这是一个递归算法。

第一位的所有情况:无非是将x1x1 与后面的所有数x2,x3,.......xnx2,x3,.......xn 依次都交换一次

示意图如下:

这里写图片描述


这里写图片描述


4.全排列的非去重递归算法

算法思路:全排列可以看做固定前i位,对第i+1位之后的再进行全排列,比如固定第一位,后面跟着n-1位的全排列。那么解决n-1位元素的全排列就能解决n位元素的全排列了,这样的设计很容易就能用递归实现。

【附代码段:】

#include<iostream>
using namespace std;
int arr[5]={0,1,2,3,4};
void swap(int x,int y)//用于交换数组的两个数
{int temp=arr[x];arr[x]=arr[y];arr[y]=temp;
}
int resove(int n)//递归函数
{if(n==5)//当尝试对不存在的数组元素进行递归时,标明所有数已经排列完成,输出。{for(int i=0;i<5;i++)cout<<arr[i]; cout<<endl;return 0;}for(int i=n;i<5;i++)//循环实现交换和之后的全排列  {//i是从n开始 i=n;swap(n,i)相当于固定当前位置,在进行下一位的排列。swap(n,i);resove(n+1);swap(n,i); }}
int main()
{resove(0);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

排列模板

void permutation1(char* str,int sbegin,int send)    //全排列的非去重递归算法  {  if( sbegin == send) //当 sbegin = send时输出  {  for(int i = 0;i <= send; i++)   //输出一个排列  cout << str[i];  cout << endl;  }  else  {  for(int i = sbegin; i <= send; i++) //循环实现交换和sbegin + 1之后的全排列  {  swap(str[i],str[sbegin]);   //把第i个和第sbegin进行交换  permutation1(str,sbegin + 1,send);  swap(str[i],str[sbegin]);   //【注1】交换回来  }  }  }  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18


【注1】swap(str[i],str[sbegin])//交换回来
我们来仔细推敲一下循环体里的代码,当我们对序列进行交换之后,就将交换后的序列除去第一个元素放入到下一次递归中去了,递归完成了再进行下一次循环。这是某一次循环程序所做的工作,这里有一个问题,那就是在进入到下一次循环时,序列是被改变了。可是,如果我们要假定第一位的所有可能性的话,那么,就必须是在建立在这些序列的初始状态一致的情况下,所以每次交换后,要还原,确保初始状态一致。

转载于:https://www.cnblogs.com/xuxinstyle/p/9742851.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/388321.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

14.并发容器之ConcurrentHashMap(JDK 1.8版本)

1.ConcurrentHashmap简介 在使用HashMap时在多线程情况下扩容会出现CPU接近100%的情况&#xff0c;因为hashmap并不是线程安全的&#xff0c;通常我们可以使用在java体系中古老的hashtable类&#xff0c;该类基本上所有的方法都采用synchronized进行线程安全的控制&#xff0c;…

modbus注意几点

1、 在利用Modbus通讯的过程中&#xff0c;遇到这样一个问题&#xff0c;即浮点数的传输问题。因为一般浮点数都是32位&#xff0c;而Modbus总线中只能传输最多16位的数据。解决方法&#xff1a;可以利用两个整形数传送一个浮点数&#xff08;即将一个32位的二进制数分割成两个…

服务器虚拟化网口,服务器安装虚拟网口

服务器安装虚拟网口 内容精选换一换Atlas 800 训练服务器(型号 9010)安装上架、服务器基础参数配置、安装操作系统等操作请参见《Atlas 800 训练服务器 用户指南 (型号9010)》。Atlas 800 训练服务器(型号 9010)适配操作系统如表1所示。请参考表2下载驱动和固件包。Atlas 800 训…

芒果云接吗_芒果糯米饭是生产力的关键吗?

芒果云接吗Would you like to know how your mood impact your sleep and how your parents influence your happiness levels?您想知道您的心情如何影响您的睡眠以及您的父母如何影响您的幸福感吗&#xff1f; Become a data nerd, and track it!成为数据书呆子&#xff0c;…

hdoj4283 You Are the One

题意&#xff1a;每个人出场时获得等待时间*值的unhappy值。有个栈换出场顺序。问怎样最小&#xff1f; 一开始的时候觉得在中间取断点&#xff0c;dp[i][j]表示区间全出场后的最小值。那么dp[i][j]dp[i][k]dp[k1][j]&#xff0c;但这样是不行的。因为有可能最优解是[i][k]只出…

laravel-admin 开发 bootstrap-treeview 扩展包

laravel-admin 扩展开发文档https://laravel-admin.org/doc... 效果图&#xff1a; 开发过程&#xff1a; 1、先创建Laravel项目&#xff0c;并集成laravel-admin&#xff0c;教程&#xff1a; http://note.youdao.com/notesh... 2、生成开发扩展包 php artisan admin:extend c…

怎么看服务器上jdk安装位置,查看云服务器jdk安装路径

查看云服务器jdk安装路径 内容精选换一换用户可以在公有云MRS集群以外的节点上使用客户端&#xff0c;在使用客户端前需要安装客户端。如果集群外的节点已安装客户端且只需要更新客户端&#xff0c;请使用安装客户端的用户例如root。针对MRS 3.x之前版本的集群&#xff0c;需要…

公司生日会生日礼物_你的生日有多受欢迎?

公司生日会生日礼物In the years before 2020, it was common for a large number of school children (20–30 or more) to physically colocate for their math lessons. And in many a class, students were asked to compute the probability that two of them had the sam…

Django思维导图

转载于:https://www.cnblogs.com/liangying666/p/9744477.html

XebiaLabs DevOps平台推出软件发布风险和合规性管理功能

XebiaLabs是DevOps和持续交付软件工具供应商&#xff0c;通过其DevOps平台推出了用于软件版本发布的监管、安全和合规风险评估跟踪功能。 这些新功能旨在帮助组织跟踪应用程序的发布状态信息&#xff0c;了解跨多个应用程序、团队和环境的安全性和合规性风险。XebiaLabs表示&am…

wp7开发环境搭建

简介 本文通过step by step的模式讲述如何从0开始搭建Window Phone 7开发环境&#xff0c;如果开发简单的Windows Phone 7程序。只是一篇介绍性的文章,但是迈进Windows Phone 7开发之路其实就那么简单,一起来开发Windows Phone 7吧。 Windows 7安装 目前Windows Phone 7开发…

旧金山字体_旧金山建筑业的兴衰。 施工趋势与历史

旧金山字体This series of articles is devoted to the study of the construction activity of the main city of Silicon Valley — San Francisco. Charts and calculations were built with the help of Jupyter Notebook (Kaggle)该系列文章专门研究硅谷主要城市旧金山的建…

gym100825G. Tray Bien(轮廓线DP)

题意:3 * N的格子 有一些点是坏的 用1X1和1X2的砖铺有多少种方法 题解:重新学了下轮廓线 写的很舒服 #include <bits/stdc.h> using namespace std; typedef long long ll;int n, m; int vis[30][5]; ll dp[25][1 << 3];void dfs(int num, int i, int state, int n…

github上打包的样式为什么在预览的时候,出现404

这是资源引用的问题 在这里主要是需要在dist的index.html文件内将"./static/css/style.css"改为"static/css/style.css",就可以加载成功了&#xff0c; 至于js的路径"./static/js/app.js"&#xff0c;就不用改了转载于:https://www.cnblogs.com/…

lambda函数,函数符_为什么您永远不应该在Lambda函数中使用print()

lambda函数&#xff0c;函数符两个Lambda用户的故事 (A Tale of Two Lambda Users) 故事1&#xff1a;业余 (Tale #1: The Amateur) One moment everything is fine, then … Bam! Your Lambda function raises an exception, you get alerted and everything changes instantl…

[ BZOJ 4668 ] 冷战

\(\\\) \(Description\) 有\(N\)个点&#xff0c;开始没有边相连&#xff0c;进行按顺序给出的\(M\)个操作&#xff1a; \(0\ u\ v\) 将\(u,v\)两点连一条边\(1\ u\ v\) 查询\(u,v\)两点最早在第几条边连接的时候被连通每次询问输出一个边的编号&#xff0c;强制在线。 \(N,M\i…

使用容器和数据库克隆进行数据库迁移

SQL Server迁移在DBA的生命周期中是一个常量&#xff0c;SQL Server 2008的支持终结正在推动大量的迁移规划。数据库迁移通常涉及将备份还原到目标环境&#xff0c;为应用程序测试提供开发和QA环境&#xff0c;以及识别已弃用的功能。当处理涉及需要数小时恢复的大量数据库的大…

C++获取PE文件的入口点

2009-10-07 10:17 C获取PE文件的入口点 源码&#xff1a; #include "stdafx.h" #include <iostream> #include <windows.h> using namespace std; int main(int argc, char* argv[]) { char *FileName argv[1]; HANDLE hFile CreateFile(FileName,GENE…