题目描述
这是 LeetCode 上的「667. 优美的排列 II」,难度为「中等」。
Tag : 「构造」、「脑筋急转弯」
给你两个整数 n
和 k
,请你构造一个答案列表 answer
,该列表应当包含从 1
到 n
的 n
个不同正整数,并同时满足下述条件:
假设该列表是
,那么列表
中应该有且仅有 k 个不同整数。
返回列表 answer
。如果存在多种答案,只需返回其中 任意一种 。
示例 1:
代码语言:javascript复制输入:n = 3, k = 1
输出:[1, 2, 3]
解释:[1, 2, 3] 包含 3 个范围在 1-3 的不同整数,并且 [1, 1] 中有且仅有 1 个不同整数:1
示例 2:
代码语言:javascript复制输入:n = 3, k = 2
输出:[1, 3, 2]
解释:[1, 3, 2] 包含 3 个范围在 1-3 的不同整数,并且 [2, 1] 中有且仅有 2 个不同整数:1 和 2
提示:
构造
给定范围在
的
个数,当「直接升序/降序」排列时,相邻项差值为
,仅一种;而从首位开始按照「升序」间隔排列,次位开始按照「降序」间隔排列(即排列为 [1, n, 2, n - 1, 3, ...]
)时,相邻差值会从
开始递减至
,共
种。
那么当我们需要构造
种序列时,我们可以先通过「直接升序」的方式构造出若干个
,然后再通过「间隔位分别升降序」的方式构造出从
到
的差值,共
个。
显然,我们需要
个数来构造出
个差值。因此我们可以先从
开始,使用
个数来直接升序(通过方式一构造出若干个
),然后从
开始间隔升序排列,按照
开始间隔降序排列,构造出剩下的序列。
Java 代码:
代码语言:javascript复制class Solution {
public int[] constructArray(int n, int k) {
int[] ans = new int[n];
int t = n - k - 1;
for (int i = 0; i < t; i ) ans[i] = i 1;
for (int i = t, a = n - k, b = n; i < n; ) {
ans[i ] = a ;
if (i < n) ans[i ] = b--;
}
return ans;
}
}
TypeScript 代码:
代码语言:javascript复制function constructArray(n: number, k: number): number[] {
const ans = new Array<number>(n).fill(0)
const t = n - k - 1
for (let i = 0; i < t; i ) ans[i] = i 1
for (let i = t, a = n - k, b = n; i < n; ) {
ans[i ] = a
if (i < n) ans[i ] = b--
}
return ans
};
- 时间复杂度:
- 空间复杂度: