leetcode
leetcode 551 ~ 600
优美的排列 II

优美的排列 II

难度:

标签:

题目描述

代码结果

运行时间: 27 ms, 内存: 16.8 MB


/* 
题目思路:
1. 通过Java Stream API,我们可以利用IntStream生成一个从1到k+1的数组,并根据索引交替选择left和right来构建前k个差值。
2. 通过IntStream生成从k+2到n的数组,添加到结果中。
*/
import java.util.stream.IntStream;
import java.util.stream.Stream;
 
public class Solution {
    public int[] constructArray(int n, int k) {
        return Stream.concat(
                IntStream.range(1, k + 2)
                        .map(i -> i % 2 == 1 ? i / 2 + 1 : n - i / 2)
                        .boxed(),
                IntStream.range(k + 2, n + 1).boxed()
        ).mapToInt(Integer::intValue).toArray();
    }
}

解释

方法:

该题解的核心思路是通过有规律的构造数字序列来生成一组特定的差值。初始时将1添加到答案列表中,然后交替地加上或减去从k开始递减到1的值,以此来构建k个不同的差值。具体地,初始方向为加法,之后每一步交替变换加法和减法操作。在完成这k个差值的构造后,剩余的数字从k+2到n依序加入列表尾部,这些后续添加的数字不会产生新的差值,因为它们相邻且连续,差值为1。

时间复杂度:

O(n)

空间复杂度:

O(n)

代码细节讲解

🦆
为什么在构造具有k个不同差值的数组后,剩余的数字需要从k+2开始添加,而不是从k+1开始?
这是因为在构造k个不同差值的过程中,最后一个数字已经是k+1或者1,具体取决于添加的是正值还是负值。如果从k+1开始添加剩余的数字,将会重复使用已经在数组中的数字,导致数组中的元素不唯一,违反题目要求。因此,从k+2开始添加可以确保所有数字都是独一无二的,并且维持数组中的连续性。
🦆
在算法中,每次操作后为什么要交替操作加法和减法?是如何保证这种交替方式能够达到题目要求的k个不同整数?
交替操作加法和减法是为了创造出k个不同的差值。例如,首先从1开始,加上一个较大的数产生一个差值,然后减去一个稍小的数产生另一个不同的差值,以此类推。这种方法可以确保每次操作后的差值都是唯一的,因为加法和减法交替使用,差值的正负符号也会交替,避免重复。通过这种策略,可以精确地控制并产生k个不同的差值,满足题目的需求。
🦆
在循环中使用的递减范围从k到1,这种设计是如何影响最终数组中差值的数量和种类的?
通过从k递减到1,算法确保了差值从最大可能的差值开始逐渐减小到1。这种递减顺序允许每次生成的差值都是唯一的,因为每次都是使用前一次未使用的最大差值。如果顺序相反,可能导致较小的差值先被生成,后续较大的差值因超出范围而无法实现,从而无法达到k个不同差值的目标。
🦆
如果k等于n-1会发生什么情况?该算法是否仍然有效?
如果k等于n-1,此时需要构造一个拥有n-1个不同差值的排列,这意味着数组中的每两个相邻数字的差都需要是唯一的。算法在这种情况下仍然有效,因为从1开始,通过交替加上和减去从n-1开始到1的值,可以确保生成所有从1到n-1的差值。这种情况下,不需要添加额外的数字,因为所有的数字都已经在构造k个不同差值的过程中被使用了。

相关问题

优美的排列

假设有从 1 到 n 的 n 个整数。用这些整数构造一个数组 perm下标从 1 开始),只要满足下述条件 之一 ,该数组就是一个 优美的排列

  • perm[i] 能够被 i 整除
  • i 能够被 perm[i] 整除

给你一个整数 n ,返回可以构造的 优美排列 数量

 

示例 1:

输入:n = 2
输出:2
解释:
第 1 个优美的排列是 [1,2]:
    - perm[1] = 1 能被 i = 1 整除
    - perm[2] = 2 能被 i = 2 整除
第 2 个优美的排列是 [2,1]:
    - perm[1] = 2 能被 i = 1 整除
    - i = 2 能被 perm[2] = 1 整除

示例 2:

输入:n = 1
输出:1

 

提示:

  • 1 <= n <= 15