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
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 } 開始每次往裡插數字應該也是可以的,奇數就在前半部分插,偶數就在後半部分插,不過每次插需要判斷插的位置對不對。