1. 程式人生 > >LC 932. Beautiful Array

LC 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.)

 

Example 1:

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

Example 2:

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

 

Note:

  • 1 <= N <= 1000
   

 

一道很好的構造題。自己沒有想出來,看了晚上的解答,但是感覺大家寫的都差不多,但沒有說到點子上。

 

1. 首先,基本的想法是讓所有的奇數放在一邊,讓所有的偶數放在另一邊,這樣能確保當以中間的數為K時,左右兩邊不會加起來有偶數出現。

2. 再考慮兩邊的情況,這個時候就不能用奇數和偶數的性質了,因為在這裡所有的數要麼都是奇數,要麼都是偶數。

這個時候,需要這樣考慮,奇數也是有順序的,比如說,1,3,5,7,9 這樣的奇數序列就是遞增的,1是第1個奇數,3是第2個奇數,5是第3個

奇數等。如果我們不是對奇數進行排列了,而是對奇數的順序進行再遞迴呼叫剛才的思想,是否能得到正確的解答呢?

這就要考慮一個問題,假設存在2k != x + y,那第k個奇數,第x個奇數,第y個奇數是否也有這樣的性質?第k個偶數,第x個偶數,第y個偶數是否也有這樣的性質?

很簡單,2(2*k-1) - (2*x-1) - (2*y-1) = 4*k - 2*x - 2*y = 2(2*k - x - y) != 0,因此這個式子是成立的。對偶數也是相同的情況。

所以,我們有這樣一個遞迴的解法。

Accepted

Runtime: 8 ms, faster than 70.97% of C++ online submissions for Beautiful Array.

class Solution {
public:
  vector<int> beautifulArray(int N) {
    if(N == 1) return {1};
    else{
      vector<int> ret;
      int oddnum = (N+1)/2;
      vector<int> oddpart = beautifulArray(oddnum);
      for(auto x : oddpart) ret.push_back(x*2-1);
      int evennum = (N)/2;
      vector<int> evenpart = beautifulArray(evennum);
      for(auto x : evenpart) ret.push_back(x*2);
      return ret;
    }
  }
};