给你两个整数
n
和k
,请你构造一个答案列表answer
,该列表应当包含从1
到n
的n
个不同正整数,并同时满足下述条件:
- 假设该列表是
answer = [a1, a2, a3, ... , an]
,那么列表[|a1 - a2|, |a2 - a3|, |a3 - a4|, ... , |an-1 - an|]
中应该有且仅有k
个不同整数。返回列表
answer
。如果存在多种答案,只需返回其中 任意一种 。示例 1:
输入:n = 3, k = 1 输出:[1, 2, 3] 解释:[1, 2, 3] 包含 3 个范围在 1-3 的不同整数,并且 [1, 1] 中有且仅有 1 个不同整数:1
示例 2:
输入:n = 3, k = 2 输出:[1, 3, 2] 解释:[1, 3, 2] 包含 3 个范围在 1-3 的不同整数,并且 [2, 1] 中有且仅有 2 个不同整数:1 和 2
提示:
1 <= k < n <= 104
解题思路
本题的题意还是比较容易理解的,我们需要构建一个这样的序列,保证所构成的序列中相邻元素的差的绝对值只有k种选择。这题是个数学题,需要找到合适方法来构建序列。
那么如何来构建呢?
- 首先分析情况,这k种差值如何来选择,是1到k还是胡乱的都行,对于这一题,由于所给的序列是1到n的有序序列,所以构建差值为1到k的更简单。
- 如何来构建包含1到k的所有差值的序列呢?因为是1到n的所有选择,所以可以根据1, 2,3…来构建,构建方式为1, k + 1, 2, k , 3,…
一直构建到差值的绝对值为1就停止,一共k+ 1个数,剩下的数就按照升序全部排列到后面,就可以保证序列中相邻元素的差值都是1到k。但是会有一个小问题需要简单证明一下。
在构建的过程中,可以发现构建出来的序列就是1到k + 1组成,但是最后一位并不确定,而后面加入的升序序列就是k + 2到n。现在知道的是后面序列的第一位是k+ 2, 但是前面序列的最后一位并不知道,他们两个的差值的绝对值会不会超过k呢?
- k为偶数
- k为奇数
证明发现,前后两个序列的两个数值差是一定小于等于k的,所以这种构建方法是合理的。
代码实现
class Solution
{
public:
vector<int> constructArray(int n, int k)
{
vector<int> res(n, 0);
//构建前面一个序列
// 1. 将1,2,3,4...放入数组
for (int i = 0, num = 1; i <= k; i += 2, num++)
res[i] = num;
// 2. 将k+1, k, k-1, k-2...放入数组
for (int i = 1, num = k + 1; i <= k; i += 2, num--)
res[i] = num;
//插入后面序列
// 3. 处理尾部数据,升序排列放入数组后面
for (int i = k + 1, num = k + 2; i < n; i++, num++)
res[i] = num;
return res;
}
};