Description:
Given two integers n and k, you need to construct a list which contains n different positive integers ranging from 1 to n and obeys the following requirement:
Suppose this list is [a1, a2, a3, ... , an], then the list [|a1 - a2|, |a2 - a3|, |a3 - a4|, ... , |an-1 - an|] has exactly k distinct integers.
If there are multiple answers, print any of them.
Example:
Example 1:
Input: n = 3, k = 1
Output: [1, 2, 3]
Explanation: The [1, 2, 3] has three different positive integers ranging from 1 to 3, and the [1, 1] has exactly 1 distinct integer: 1.
Example 2:
Input: n = 3, k = 2
Output: [1, 3, 2]
Explanation: The [1, 3, 2] has three different positive integers ranging from 1 to 3, and the [2, 1] has exactly 2 distinct integers: 1 and 2.
Link:
https://leetcode.com/problems/beautiful-arrangement-ii/description/
解題方法:
當我們有1~n這些數的時候,k最多可以是n - 1個,其排列遵循:
1, 1 + k, 2, k, 3, k - 1, ...
有一點可以確定就是,這個序列的最后兩個數的差肯定是個1,那么當我們需要k個不同的數時,
- 直接可以取1~k+1這些數來進行以上的排序;
2 .而剩下的數(k + 2 ~ n)則可以直接接到數組的后面。并且不會增加k的值,因為前面提到之前序列最后兩個數的差肯定是1并且后面接上的數組每兩個數的差也會是1。
舉個例子:
假設n = 9, k = 4.
按照上面的步驟一,我們先取1~5來組成前面的數組:
1 5 2 4 3
差值數組為:
4 3 2 1
然后我們接上剩下的數6~9,獲得結果:
1 5 2 4 3 6 7 8 9
這里有一點可以確定,接上的數組第一個數與之前數組最后一個數的差值肯定會在之前那個數的差值數組里產生(數學問題)。
Tips:
在生成第一段數組時,我們需要添加個判斷條件,防止k為偶數時,添加錯誤(見以下代碼)。
Time Complexity:
O(n)
完整代碼:
vector<int> constructArray(int n, int k)
{
vector<int> result;
int a = 1, b = 1 + k;
while(a <= b)
{
result.push_back(a++);
if(a <= b)
result.push_back(b--); //tips
}
for(int i = k + 2; i <= n; i++)
result.push_back(i);
return result;
}