完美洗牌問題

2021-06-25 12:04:03 字數 1445 閱讀 3090



完美洗牌問題:

(一)有長度為2n的陣列,希望排序後為,希望時間複雜度為o(n),空間複雜度為o(1)

(二)解析:有兩副牌,乙個人拿的牌為a1,a2,a3...an,另乙個人的牌為b1,b2...bn,兩個人交叉出牌,則牌的順序就可以為a1,a2,b1,b2,...an,bn或者b1,a1,b2,a2..bn,an

(a1,b1,a2,b2...)到(b1,a1,b2,a2....)只需要奇數遍歷一遍,然後當前元素與後面的元素交換即可。時間複雜度為o(n)

(三)解決:

(1)方法一:

時間複雜度為o(n),空間複雜度為o(n)

根據陣列,將前n個資料進入乙個佇列,後n個資料進入乙個佇列,然後依次輪流出佇列即可。

(2)方法二:

時間複雜度為o(n^2),空間複雜度為o(1);

如:a1,a2,..an,b1,b2..bn

首先定位到b1的位置,然後將b1與a1之間的元素a2...an整體交換,即(a2..an,b1)迴圈右移一位,即a1,a2..an,b1,b2..bn->a1,b1,a2..an,b2..bn;

然後在將b2,a2之間的元素a3,a4..an與b2交換。。。。。

(3)方法三:分治法

時間複雜度為o(n*lgn),空間複雜度為o(1)

如:當n為偶數時,如a1,a2,a3,a4,b1,b2,b3,b4,

將中間的n個元素迴圈右移n/2次,得到a1,a2,b1,b2,a3,a4,b3,b4。

然後求解子問題a1,a2,b1,b2和a3,a4,b3,b4即可。

如果n為奇數,如n=5,如a1,a2,a3,a4,a5,b1,b2,b3,b4,b5則先將a5與後面的所有元素迴圈左移一位,即變成a1,a2,a3,a4,b1,b2,b3,b4,b5,a5,此時的b5,a5已經是我們要的結果了,只需要考慮n=4的情況了。

所以t(n)=2t(n/2)+o(n)

2)**實現如下:

/*a為陣列,halflen為陣列長度的一半,所以總長度為2*halflen。

即halflen為每個人手中的牌數目

陣列的下標是從1開始,即陣列從a[1,2*halflen]

*/void prefect_shuffle2(int *a ,int halflen)

int totallen=2*halflen;

int quarterlen=halflen/2;

int i;

if(halflen%2==1)

a[totallen]=tempdata;

halflen--;

}//此時halflen為偶數

for(i=quarterlen+1;i<=halflen;i++)

perfect_shuffle2(a,quarterlen);

perfect_shuffle2(a+n,quarterlen);

}(4)方法四:

完美洗牌 洗牌

完美洗牌問題,給定乙個陣列a1,a2,a3,an,b1,b2,b3.bn,把它最終設定為b1,a1,b2,a2,bn,an這樣的。o n 的演算法,o n 的空間。對於前n個數,對映為f i 2 i 1,0 i n 2 比如0 1,1 3 對於後n個數,對映為f i 2 i n 2 n 2 i n ...

完美洗牌演算法

原文 完美洗牌問題 給定乙個陣列a1,a2,a3,an,b1,b2,b3.bn,把它最終設定為b1,a1,b2,a2,bn,an這樣的。分析 首先,有的問題要求把它換成a1,b1,a2,b2,an,bn。其實也差不多。我們可以 迴圈n次交換a1,b1,a2,b2,把陣列變為b1,b2.bn,a1,a...

完美洗牌演算法

沒把空間複雜度o 1 的搬過來 問題描述 有乙個長度為2n的陣列,希望排序後變成,請考慮有沒有時間複雜度為o n 而空間複雜度為o 1 的解法。string a string temp new string len for int i 1 i len i temp 2 i len a i 經過上面處...