【leetcode 932】漂亮陣列 Beautiful Array (構造)
題目:
給定一個排列,要求給出其滿足對於任意一個數A[k],使得i<k<j,2*A[k]!=A[i]+A[j].的一個排列
思路:
構造題,emmmm,emmmmmm
先看一種簡單的思路。
因為2*A[k]是偶數,如果要求2*A[K]!=A[I]+A[J]那麼可以構造位置在A[k]左邊的全部放奇數,位置在A[k]右邊的全部放偶數。這樣就保證了對於K位置而言,這個性質是滿足的。
也許你就有疑問了,1,3,5,6,2,4.這組序列中,雖然對於6位置而言,左邊全是奇數,右邊全是偶數,但是全是奇數的那一邊明顯不滿足要求。怎麼解決呢?
習慣從幼兒園開始就要養成,左邊是奇數,右邊是偶數的形式也得從N比較小的時候開始。這裡有一個遞迴的思想。因為長度為N的序列中,奇數個數為(N+1)/2,偶數個數為N/2,所以Beautiful Array(N)的排列,可以由Beautiful Array(N/2)和Beautiful Array((N+1)/2)組成,為什麼這麼說呢?
假設N = 7,那麼Beautiful Array(N/2) = 1,,3,2(滿足題目性質) Beautiful Array((N+1)/2) = 1 3 2 4.(滿足題目性質)
那麼 2*Beautiful Array((N+1)/2)-1(奇數在前)連線 2*Beautiful Array(N/2) = 1 5 3 7 | 2 6 4.(逐個元素進行操作)
我們可以觀察到,對於這個分隔符而言,左邊是奇數,右邊是偶數,所以在分隔符位置,無疑是滿足題目要求的性質的。而且,左邊的奇數是從滿足題目性質的陣列進行線性運算得出的,所以並不會影響各個位置數字間的性質,(如1,3,5. 2*3==1+5,同時乘2之後這個性質依然成立)。既然組成這個大陣列的子陣列Beautiful Array(N/2)和Beautiful Array((N+1)/2)都滿足性質,那麼乘法之後的陣列也依然滿足題目要求。所以大陣列左半部分和右半部分都滿足題目要求。而中間分隔位置也滿足性質,所以這一整個大陣列也滿足題目性質了。所以我們只需要保證Beautiful Array(1)滿足題目性質就可以遞推出所有的Beautiful Array(N)了。很明顯Beautiful Array(1)沒有別的選擇,只能滿足性質。
程式碼:
class Solution {
public:
vector<int> beautifulArray(int N){
vector<int>ans;
if(N==1){
ans.push_back(1);return ans;
}
else {
vector<int>ve = beautifulArray((N+1)/2);
int sz = ve.size();
for(int it=0;it<sz;it++)ans.push_back(2*ve[it]-1);
vector<int>vv = beautifulArray(N/2);
sz = vv.size();
for(int it=0;it<sz;it++)ans.push_back(2*vv[it]);
}
return ans;
}
};