完美洗牌 洗牌

2022-07-29 09:06:06 字數 1186 閱讀 5727

完美洗牌問題,給定乙個陣列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; 比如n/2->0, n/2 + 1->2... 並且f(i) =2(i - n/2)=2*i-n=2*i+1-(n+1)=(2*i+1)%(n+1)。

統一起來,對映為f(i) = (2 * i + 1) % (n + 1).

1

void perfectshuffle1(int arr, int

n) 6

for (int i = 0; i < n; ++i)

9delete tmp;

10 }

分治法,o(nlgn)的演算法,o(lgn)的空間。

line 4-11 主要就是處理好陣列的一半為奇數的情部分。

當n/4!=0的時候,陣列的一半為奇數。此時要將[n/2,n)的數往左移,把第n/2-1個數(前一半的最後乙個數)放到末尾,這樣,最後兩個數就排好了。問題就轉化成了陣列的一半是偶數的情況。

當陣列的一半是偶數時,只需要把前一半的後半部分和後一半的前半部分交換一下,就達到分治的目的了。

1

void perfectshuffle2(int arr, int

n) 9 arr[n - 1] =tmp;

10 n -= 2;11

}12for (int i = 0; i < n / 4; ++i)

15 perfectshuffle2(arr, n / 2

);16 perfectshuffle2(arr + n / 2, n / 2

);17 }

主要參考自: 裡面提到的第三種解法沒去看,感覺面試不會考就先不費力去理解了。

洗牌的問題就比較簡單,其實相當於從陣列中隨機選出m個數,見之前的博文。只不過這裡m=n而已。

1

void shuffle(int arr, int

n) 6 }

這個和網上提到的fisheryates洗牌演算法的原理是一樣的。

完美洗牌演算法

原文 完美洗牌問題 給定乙個陣列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...

完美洗牌問題

完美洗牌問題 一 有長度為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,...

完美洗牌演算法

沒把空間複雜度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 經過上面處...