天天看点

667. 优美的排列 II : 常规构造题

题目描述

这是 LeetCode 上的 667. 优美的排列 II ,难度为 中等。

Tag : 「构造」、「脑筋急转弯」

给你两个整数 ​

​n​

​​ 和 ​

​k​

​​ ,请你构造一个答案列表 ​

​answer​

​​,该列表应当包含从 ​

​1​

​​ 到 ​

​n​

​​ 的 ​

​n​

​ 个不同正整数,并同时满足下述条件:

假设该列表是 ,那么列表

返回列表 ​

​answer​

​。如果存在多种答案,只需返回其中 任意一种 。

示例 1:

输入:n = 3, k = 1

输出:[1, 2, 3]

解释:[1, 2, 3] 包含 3 个范围在 1-3 的不同整数,并且 [1, 1]      

示例 2:

输入:n = 3, k = 2

输出:[1, 3, 2]

解释:[1, 3, 2] 包含 3 个范围在 1-3 的不同整数,并且 [2, 1]      

提示:

构造

给定范围在 的 个数,当「直接升序/降序」排列时,相邻项差值为 ,仅一种;而从首位开始按照「升序」间隔排列,次位开始按照「降序」间隔排列(即排列为 ​​

​[1, n, 2, n - 1, 3, ...]​

​​)时,相邻差值会从 开始递减至 ,共

那么当我们需要构造 种序列时,我们可以先通过「直接升序」的方式构造出若干个 ,然后再通过「间隔位分别升降序」的方式构造出从 到 的差值,共

显然,我们需要 个数来构造出 个差值。因此我们可以先从 开始,使用 个数来直接升序(通过方式一构造出若干个 ),然后从 开始间隔升序排列,按照

Java 代码:

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      

TypeScript 代码:

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      
  • 时间复杂度:
  • 空间复杂度:

最后

这是我们「刷穿 LeetCode」系列文章的第 ​

​No.667​

​ 篇,系列开始于 2021/01/01,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先把所有不带锁的题目刷完。

在这个系列文章里面,除了讲解解题思路以外,还会尽可能给出最为简洁的代码。如果涉及通解还会相应的代码模板。