日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

next_permutation算法(基于交换)

發布時間:2023/12/10 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 next_permutation算法(基于交换) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

nextpermutation 算法
這個算法如何實現 我們要觀察對于任意的123456
對于一個任意的字符串
我們如果要找他的下一個全排列
就應該變動其數字 使得其數值增大 且是最小的增大
那么僅使用以上數字 如何才能使其變大 但變大的數字 是所有變大范圍內最小的可能 我們稱其為 最小變大


我們看 如果是 1234 下一個數 1243
再來 1243 下一個數是 1342
那么 1342 下一個數是 1423 > 1432
1432 > 2134

像4,43,432這種時候
就需要 把后面的一個數字和前面的一個數字更換
從而實現到最小變大 那么進一步地
我們發現 每次這種變化都是一個遞減序列 (如 4,43,432)
把其中最小的數字 和4前面的數字交換 得到一個新序列
因為只有這樣才能保證 我們得到新序列才是向“最小變大”

我們需要在后面的遞減序列中找到一個比遞減序列第一個元素前的
那個元素 我們姑且叫他第0號元素 我們找到一個比0號元素大的
且是最接近0號元素的數字 和 0號交換 才能實現“最小變大“

好了 那么 我們就有代碼的思路了
我們發現 任何數串 都可以看成一個后面拖著一個遞減序列的數串
無論是什么數字 后面總有一個遞減序列 有的是一個元素,有的是多個元素

如何找到他下一個排列?我們要做的是
把遞減序列前的第0元素 和遞減序列中的比0號元素大且最接近的元素
他倆交換 這樣才能實現變大 而且可以推得 遞減序列中一定存在元素比第0號元素大

為什么呢? 因為若是不這樣 0號元素就在非嚴格
遞減序列里了 所以一定遞減序列中有元素比他大
那么 交換完成后就完成任務了嗎? 還不夠
比如 1342 ?> 1432 >1423
? ? ? ? 1 ? ? ?2 ? ? 3

我們發現 還需要調整一下才能得到交換后的數串最小
如何調整? 就是要把交換后原來的遞減序列從小到大排序才能使其最小
所以我們這里就知道了 由于交換后的0號元素新位置 本來就比0號大
所以仍舊是遞減序列

那么就總結為這幾個步驟

1 找出遞減序列前的第0元素
2 找出遞減序列中大于第0元素的最接近元素
3 交換兩個元素
4 將0號元素后的序列從小到大排序

我們就得到了他的下一排列

?

模板例題:POJ-3785

題意:就是求下一個排列

?

#include<cstdio> #include<iostream> #include<algorithm> #include<cstring> using namespace std; char a[100]; bool Next(int s,int e){int l,j = e-1;while(j>0&&a[j]>=a[j+1])j--; //1if(j==0)return 0;//如果完全逆序 則不必交換 已經是最大可能了for(l = e;a[l]<=a[j];l--);//2swap(a[l],a[j]);//3reverse(a+j+1,a+e+1);//4return 1; } int main(){int n;scanf("%d",&n);while(n--){int num;scanf("%d %s",&num,a+1);int len = strlen(a+1);if(Next(1,len))printf("%d %s\n",num,a+1);else printf("%d BIGGEST\n",num);}return 0; }

?

總結

以上是生活随笔為你收集整理的next_permutation算法(基于交换)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。