一、下乙個排列
首先,stl提供了兩個用來計算排列組合關係的演算法,分別是next_permutation和prev_permutation。
next_permutation(nums.begin(),nums.end());//下乙個排列
prev_permutation(nums.begin(),nums.end())//上乙個排列
當返回為1時,表示找到了下一全排列;返回0時,表示無下一全排列
1.1下乙個排列演算法過程
(1)從右到左,找到第乙個違反遞增趨勢的分割槽數;例如下圖的6。
(2)從右到左,找到第乙個比分區數大的改變量;例如下圖的7。
(3)交換分割槽數和改變量;例如下圖的6和7交換。
(4)顛倒分割槽數索引的右邊所有數字。例如下圖的7之後的元素。
1.2 stl原始碼剖析中的演算法過程
(1)首先從最尾端開始往前尋找兩個相鄰元素,令第一元素為*i,第二元素為*ii,且滿足*i
(2)找到這樣一組相鄰元素後,再從最尾端開始往前檢驗,找出第乙個大於*i的元素,令為*j,將i,j元素對調(swap)。
(3)再將ii之後的所有元素顛倒(reverse)排序。
1.3 版本一實現細節(c指標實現)
templatebool1.4版本二實現細節(純stl規範)next_permutation(bidrectionaliterator first,bidrectionaliterator last)
if(i == first) /*
進行至最前面了
*/ }
}
1 template21.5 前乙個排列(prev_permutation)bool
next_permutation(bidiit first,bidiit last) 3
1718 auto change=find_if(rfirst,rlast,bindlst(less(),*pivot));//
從右到左,找到第乙個大於分割槽數的數,並賦給change;
1920 swep(*change,*pivot);//
交換分割槽數與改變量;
2122 reverse(rfirst,pivot);//
將分割槽數之後的序列顛倒;
2324
return
true
;
25 }
與next_permutation類似,stl也提供乙個版本:
1二、全排列int prev_permutation(int *begin, int *end)215
//current is in ascending order
16reverse(begin,end);
17return0;
18 }
1.1 利用next_permutation求全排列
對初始序列依次求下乙個排列,直到沒有下乙個序列為止。
舉個例項,假設有序列,下圖便是套用上述演演算法則,一步一步獲得「下乙個」排列組合。圖中只框出那符合「一元素為*i,第二元素為*ii,且滿足*i
**如下:
vectorint>> permute(vector&nums)1.2 利用深度優先搜尋(dfs)求解,以後待更新。while(next_permutation(nums.begin(),nums.end()));//
do while迴圈最適合,因為先要列印出初始序列
return
result;
}
三、第k個排列
簡單的,可以用暴力列舉法,呼叫k-1次next_permutation()(注意一定是k-1次)
**如下:
1string getpermutation(int n, int
k)
下乙個排列
給定乙個若干整數的排列,給出按正數大小進行字典序從小到大排序後的下乙個排列。如果沒有下乙個排列,則輸出字典序最小的序列。樣例 左邊是原始排列,右邊是對應的下乙個排列。1,2,3 1,3,2 3,2,1 1,2,3 1,1,5 1,5,1 思路 1 先從右到左找到第乙個不屬於非最大字典序排列的元素l,...
下乙個排列
給定乙個若干整數的排列,給出按正數大小進行字典序從小到大排序後的下乙個排列。如果沒有下乙個排列,則輸出字典序最小的序列。左邊是原始排列,右邊是對應的下乙個排列。1,2,3 1,3,2 3,2,1 1,2,3 1,1,5 1,5,1 剛開始看這個題目沒有看懂,在網上蒐集一番資料後,懂得了題目想要做的事...
下乙個排列
實現獲取下乙個排列的函式,演算法需要將給定數字序列重新排列成字典序中下乙個更大的排列。如果不存在下乙個更大的排列,則將數字重新排列成最小的排列 即公升序排列 必須原地修改,只允許使用額外常數空間。以下是一些例子,輸入位於左側列,其相應輸出位於右側列。1,2,3 1,3,2 3,2,1 1,2,3 1...