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 constructArray(int n, int k)
{
vector 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;
}