1. 程式人生 > >【leetcode 932】漂亮陣列 Beautiful Array (構造)

【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;
}

};