1. 程式人生 > >LeetCode - 932. Beautiful Array

LeetCode - 932. Beautiful Array

932. Beautiful Array

For some fixed N, an array A is beautiful if it is a permutation of the integers 1, 2, ..., N, such that:

For every i < j, there is no k with i < k < j such that A[k] * 2 = A[i] + A[j].

Given N

, return any beautiful array A.  (It is guaranteed that one exists.) 1 <= N <= 1000

Input: 4          Output: [2,1,4,3]

Input: 5          Output: [3,1,2,5,4]

解:

    第一反應是從 vecctor<int> res = { 1 }; 開始,一個數一個數往裡插,不過看到判斷條件是 A[k] * 2 == A[i] + A[j] 就想到,這不是向下取整,所以如果 A[i] + A[j] 一個是奇數一個是偶數(也就是兩個的和是奇數),那一定不會有 k 使得 A[k] * 2(偶數) 等於兩個數的和,那如果有一個全是奇數的 Beautiful Array(比如叫 Odd ),和一個全是偶數的 Beautiful Array(比如叫 Even ),那這兩個拼接起來一定也是 Beautiful Array(因為隨機選 i 和 j 的位置,如果都在 Odd 裡,或者都在 Even 裡,那因為他們兩個都是 Beautiful Array 肯定滿足條件,如果一邊一個,那因為上邊的分析,條件也是滿足的)。

    如果 N 是奇數(比如 7 ),那就是 Odd 裡邊有 4 個數(1 3 5 7),Even 裡邊有三個數(2 4 6);如果 N 是偶數(比如 6 ),那就是 Odd 裡邊有 3 個數(1 3 5),Even 裡邊有 3 個數(2 4 6)。最短的 Beautiful Array(N = 1時) 是 { 1 } 這個顯而易見。現在要做的就是從基礎的 Beautiful Array 一點一點擴充套件成 N 長度的 Beautiful Array。

    Beautiful Array 有兩個很重要的性質可以分析出來:

  • 如果 A 是 Beautiful Array,那麼 A * 2 - 1 也是 Beautiful Array(這就變成了全是奇數的 Beautiful Array )
  • 如果 A 是 Beautiful Array,那麼 A * 2       也是 Beautiful Array(這就變成了全是偶數的 Beautiful Array )

這樣,(A * 2 + 1)和(A * 2)拼接起來,就是 N * 2 長度的 Beautiful Array。每次可以擴充一倍,10次就是 1024 倍,因為題目說了 N <= 1000,那麼從 { 1 } 這個 Beautiful Array 到 N = 1000 的 Beautiful Array 就需要 10 次擴充。中間的結果把大於 N 的數刪掉就行了。

vector<int> beautifulArray(int N) {
    vector<int> res = { 1 };
    while(res.size() < N)
    {
        vector<int> tmp;
        for(auto r : res)
            if(r * 2 - 1 <= N)
                tmp.push_back(r * 2 - 1);
        for(auto r : res)
            if(r * 2 <= N)
                tmp.push_back(r * 2);
        res = tmp;
    }
    return res;
}

    把每次的結果輸出出來,或者手算一下更容易理解:

  • N = 1,res = { 1 }
  • N = 2,res = { 1, 2 }
  • N = 3,res = { 1, 3, 2 }
  • N = 4,res = { 1, 3, 2, 4 }
  • N = 5,res = { 1, 5, 3, 2, 4 }
  • N = 6,res = { 1, 5, 3, 2, 6, 4 }
  • N = 7,res = { 1, 5, 3, 7, 2, 6, 4 }
  • ......

    其實從 { 1, 2 } 開始每次往裡插數字應該也是可以的,奇數就在前半部分插,偶數就在後半部分插,不過每次插需要判斷插的位置對不對。