排列組合的計算方法

問題

求1,2,3...n的不同排列方式(n!)

思路

普通的排列問題铸史,在python庫中甚至有現(xiàn)成的庫可以用來解決缩膝,我們這里考慮兩種方案膜蠢,首先是回溯的思路(遞歸):
基于交換元素的回溯實現(xiàn)較為簡單膜楷,每一次交換循環(huán)位置的元素和首元素砾嫉,直到循環(huán)位置抵達末尾抡砂,交換完畢后回溯

當(dāng)然也有其他的思路大咱,比如使用一個mark數(shù)組記錄當(dāng)前去過的位置,然后每次找下一個沒去過的位置注益,這種方法其實也屬于回溯碴巾,比較容易理解其正確性

其次是非遞歸的實現(xiàn),這里我還沒有沒有找到與遞歸等同效率的思路(目前時間復(fù)雜度要高出On)丑搔,只能暫時記錄下來留待之后改進了

這里主要思想是既然一共有n!個排列厦瓢,那么n的排列相當(dāng)于n-1的所有排列*n,得到n-1的所有排列后啤月,其實只需在每種排列上加上1-n就行了

解決

# 遞歸
def rec(a, l, r):
    if l==r:
        print(*a)
        return
    for i in range(l, r+1):#注意這里下限是l煮仇,雖然把自己跟自己交換是一種重復(fù),但這也是需要計算在內(nèi)的
        a[i], a[l] = a[l], a[i]
        rec(a,l+1,r)
        a[i], a[l] = a[l], a[i]
rec([i+1 for i in range(n)], 0, n-1)
# 非遞歸
n = 4
t, steps = 1, [[1]]
while t < n:
    cur, t = [], t+1
    for i in range(1, t+1):
        for s in steps:
            cur.append([i, *[(i+x-1) % t+1 for x in s]])
    steps = cur
    print(*steps) #[1, 2, 3, 4] [1, 2, 4, 3] [1, 3, 4, 2] [1, 3, 2, 4] [1, 4, 2, 3] [1, 4, 3, 2] [2, 3, 4, 1] [2, 3, 1, 4]...

問題

求1-n中取出x個數(shù)字的方式(C(n,x))

思路

同樣考慮兩種方式谎仲,首先是遞歸浙垫,記錄當(dāng)前位置和遞歸深度即可,遞歸深度為x即取數(shù)完畢

第二是非遞歸郑诺,這里運用了一點bit magic夹姥,大概意思是根據(jù)x二進制中最大遞增后綴序列求出下一個排列,具體可以參見這篇文章

解決

# 遞歸
def comb(n,x,cur,start,depth,arr):
    if depth==x:
        arr.append(cur)
        return
    for next in range(start,n-x+depth+1):
        comb(n,x,cur+str(next),next+1,depth+1,arr)
comb(n,x,'',0,0,arr) # 01 02 03 04 12 13 14 23 24 34辙诞,這里下標(biāo)是0開始的辙售,不影響效果
# 非遞歸
n, x = 5, 3
start, end = (1 << c)-1, (1 << n) - (1 << (n-x)) # 這里start和end就是二進制中x個1在最開始和最末尾的數(shù)
v = start
while v <= end:
    # 這里結(jié)果所對應(yīng)的二進制位為1的下標(biāo)就是具體的組合
    print(bin(v)[2:].rjust(n, '0'))
    # 下面兩行是求next permutation的位運算方法,具體解釋可以參考引用的兩篇資料
    t = (v | (v - 1)) + 1 
    w = t | ((int((t & -t) / (v & -v)) >> 1) - 1)
    v = w

Ref

https://www.geeksforgeeks.org/write-a-c-program-to-print-all-permutations-of-a-given-string/
http://blog.gaurav.im/2016/12/18/next-binary-permutation-bitwise-hackery/
https://graphics.stanford.edu/~seander/bithacks.html#NextBitPermutation

Tips

  • x & -x是求x的二進制中最右邊的1所對應(yīng)位置的二進制數(shù)倘要,比如x=01100100圾亏,x&-x=00000100十拣,x為奇數(shù)這個值就一定是1
  • x | x-1是將x的二進制中所有后繼0置1封拧,比如x=01100100,x&-x=01100111夭问,同樣x為奇數(shù)這個值就是本身
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子萌焰,更是在濱河造成了極大的恐慌倘核,老刑警劉巖陕见,帶你破解...
    沈念sama閱讀 217,542評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異味抖,居然都是意外死亡评甜,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評論 3 394
  • 文/潘曉璐 我一進店門仔涩,熙熙樓的掌柜王于貴愁眉苦臉地迎上來忍坷,“玉大人,你說我怎么就攤上這事熔脂∨逖校” “怎么了?”我有些...
    開封第一講書人閱讀 163,912評論 0 354
  • 文/不壞的土叔 我叫張陵霞揉,是天一觀的道長旬薯。 經(jīng)常有香客問我,道長适秩,這世上最難降的妖魔是什么绊序? 我笑而不...
    開封第一講書人閱讀 58,449評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮隶症,結(jié)果婚禮上政模,老公的妹妹穿的比我還像新娘。我一直安慰自己蚂会,他們只是感情好淋样,可當(dāng)我...
    茶點故事閱讀 67,500評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著胁住,像睡著了一般趁猴。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上彪见,一...
    開封第一講書人閱讀 51,370評論 1 302
  • 那天儡司,我揣著相機與錄音,去河邊找鬼余指。 笑死捕犬,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的酵镜。 我是一名探鬼主播碉碉,決...
    沈念sama閱讀 40,193評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼淮韭!你這毒婦竟也來了垢粮?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,074評論 0 276
  • 序言:老撾萬榮一對情侶失蹤靠粪,失蹤者是張志新(化名)和其女友劉穎蜡吧,沒想到半個月后毫蚓,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,505評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡昔善,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,722評論 3 335
  • 正文 我和宋清朗相戀三年元潘,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片君仆。...
    茶點故事閱讀 39,841評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡柬批,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出袖订,到底是詐尸還是另有隱情氮帐,我是刑警寧澤,帶...
    沈念sama閱讀 35,569評論 5 345
  • 正文 年R本政府宣布洛姑,位于F島的核電站上沐,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏楞艾。R本人自食惡果不足惜参咙,卻給世界環(huán)境...
    茶點故事閱讀 41,168評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望硫眯。 院中可真熱鬧蕴侧,春花似錦、人聲如沸两入。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽裹纳。三九已至择葡,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間剃氧,已是汗流浹背敏储。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留朋鞍,地道東北人已添。 一個月前我還...
    沈念sama閱讀 47,962評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像滥酥,于是被迫代替她去往敵國和親更舞。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,781評論 2 354