全排列算法實現

版權聲明:本文為博主原創文章,未經博主允許不得轉載。 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(n?n!)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,........xn?1,xnx2,x3,x4,x5,........xn?1,xn】

我們獲得了在第一個位置上的所有情況之后(注:是所有的情況),對每一種情況,抽去序列TT 中的第一個位置,那么對于剩下的序列可以看成是一個全新的序列

T1=x2,x3,x4,x5,........xn?1,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.pswp.cn/news/388321.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/388321.shtml
英文地址,請注明出處:http://en.pswp.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…