数组题目:优美的排列 II

文章目录

题目

标题和出处

标题:优美的排列 II

出处:667. 优美的排列 II

难度

7 级

题目描述

要求

给你两个整数 n \texttt{n} n 和 k \texttt{k} k,请你构造一个答案列表 answer \texttt{answer} answer,该列表应当包含从 1 \texttt{1} 1 到 n \texttt{n} n 的 n \texttt{n} n 个不同正整数,并同时满足下述条件:

  • 假设该列表是 answer = [ a 1 , a 2 , a 3 , … , a n ] \texttt{answer} = [\texttt{a}_\texttt{1}, \texttt{a}_\texttt{2}, \texttt{a}_\texttt{3}, \ldots, \texttt{a}_\texttt{n}] answer=[a1​,a2​,a3​,…,an​],那么列表 [ ∣ a 1 − a 2 ∣ , ∣ a 2 − a 3 ∣ , ∣ a 3 − a 4 ∣ , … , ∣ a n-1 − a n ∣ ] [|\texttt{a}_\texttt{1} - \texttt{a}_\texttt{2}|, |\texttt{a}_\texttt{2} - \texttt{a}_\texttt{3}|, |\texttt{a}_\texttt{3} - \texttt{a}_\texttt{4}|, \ldots, |\texttt{a}_\texttt{n-1} - \texttt{a}_\texttt{n}|] [∣a1​−a2​∣,∣a2​−a3​∣,∣a3​−a4​∣,…,∣an-1​−an​∣] 中应该有且仅有 k \texttt{k} k 个不同整数。

返回列表 answer \texttt{answer} answer。如果存在多种答案,只需返回其中任意一种

示例

示例 1:

输入: n   =   3,   k   =   1 \texttt{n = 3, k = 1} n = 3, k = 1
输出: [1,   2,   3] \texttt{[1, 2, 3]} [1, 2, 3]
解释: [1,   2,   3] \texttt{[1, 2, 3]} [1, 2, 3] 包含 3 \texttt{3} 3 个范围在 1 \texttt{1} 1 到 3 \texttt{3} 3 的不同整数,并且 [1,   1] \texttt{[1, 1]} [1, 1] 中有且仅有 1 \texttt{1} 1 个不同整数: 1 \texttt{1} 1

示例 2:

输入: n   =   3,   k   =   2 \texttt{n = 3, k = 2} n = 3, k = 2
输出: [1,   3,   2] \texttt{[1, 3, 2]} [1, 3, 2]
解释: [1,   3,   2] \texttt{[1, 3, 2]} [1, 3, 2] 包含 3 \texttt{3} 3 个范围在 1 \texttt{1} 1 到 3 \texttt{3} 3 的不同整数,并且 [2,   1] \texttt{[2, 1]} [2, 1] 中有且仅有 2 \texttt{2} 2 个不同整数: 1 \texttt{1} 1 和 2 \texttt{2} 2

数据范围

  • 1 ≤ k < n ≤ 10 4 \texttt{1} \le \texttt{k} < \texttt{n} \le \texttt{10}^\texttt{4} 1≤k<n≤104

解法

思路和算法

为了方便叙述,将列表 [ ∣ a 1 − a 2 ∣ , ∣ a 2 − a 3 ∣ , ∣ a 3 − a 4 ∣ , … , ∣ a n − 1 − a n ∣ ] [|a_1 - a_2|, |a_2 - a_3|, |a_3 - a_4|, \ldots, |a_{n-1} - a_n|] [∣a1​−a2​∣,∣a2​−a3​∣,∣a3​−a4​∣,…,∣an−1​−an​∣] 称为「相邻绝对差列表」。

对于从 1 1 1 到 n n n 的任意排列,对应的「相邻绝对差列表」中的不同整数最少为 1 1 1 个,即所有的相邻元素绝对差都相等,最多为 n − 1 n-1 n−1 个,即所有的相邻元素绝对差都不相等。

对于列表 [ 1 , 2 , 3 , … , n ] [1, 2, 3, \ldots, n] [1,2,3,…,n],「相邻绝对差列表」中的元素都是 1 1 1,因此有 1 1 1 个不同整数。

对于列表 [ 1 , n , 2 , n − 1 , 3 , n − 2 , … ] [1, n, 2, n - 1, 3, n - 2, \ldots] [1,n,2,n−1,3,n−2,…],「相邻绝对差列表」中的元素各不相同,分别为 n − 1 n-1 n−1 到 1 1 1,因此有 n − 1 n-1 n−1 个不同整数。

为了让「相邻绝对差列表」中的不同整数为 k k k 个,可以从整数 1 1 1 到 k + 1 k+1 k+1 构造出「相邻绝对差列表」中的元素各不相同的序列: [ 1 , k + 1 , 2 , k , 3 , k − 1 , … ] [1, k + 1, 2, k, 3, k - 1, \ldots] [1,k+1,2,k,3,k−1,…],然后将从 k + 2 k+2 k+2 到 n n n 的整数依次添加到该序列的末尾。

按照上述方法构造出的序列,前 k + 1 k+1 k+1 个数的相邻元素绝对差各不相同,分别为 k k k 到 1 1 1,从 k + 2 k+2 k+2 到 n n n 的相邻元素绝对差都是 1 1 1, k + 2 k+2 k+2 前面的相邻元素一定大于 1 1 1,因此 k + 2 k+2 k+2 和前面的相邻元素的绝对差一定不超过 k k k。即整个序列的「相邻绝对差列表」包含从 1 1 1 到 k k k 的全部整数,且不包含大于 k k k 的整数,因此「相邻绝对差列表」中有且仅有 k k k 个不同整数。

证明

对于列表 [ 1 , n , 2 , n − 1 , 3 , n − 2 , … ] [1, n, 2, n - 1, 3, n - 2, \ldots] [1,n,2,n−1,3,n−2,…],「相邻绝对差列表」中的元素各不相同,分别为 n − 1 n-1 n−1 到 1 1 1,有 n − 1 n-1 n−1 个不同整数。该结论证明如下。

用 arr \textit{arr} arr 表示列表 [ 1 , n , 2 , n − 1 , 3 , n − 2 , … ] [1, n, 2, n - 1, 3, n - 2, \ldots] [1,n,2,n−1,3,n−2,…],则 arr \textit{arr} arr 中的每个下标对应的元素如下:

arr [ i ] = { i 2 + 1 , i   是 偶 数 n − i − 1 2 , i   是 奇 数 \textit{arr}[i]=\begin{cases} \dfrac{i}{2}+1, & i~是偶数 \\ n-\dfrac{i-1}{2}, & i~是奇数 \end{cases} arr[i]=⎩⎪⎨⎪⎧​2i​+1,n−2i−1​,​i 是偶数i 是奇数​

当 1 ≤ i < n 1 \le i < n 1≤i<n 时, arr [ i ] − arr [ i − 1 ] \textit{arr}[i]-\textit{arr}[i-1] arr[i]−arr[i−1] 计算如下:

  • 当 i i i 是奇数时:

  arr [ i ] − arr [ i − 1 ] = ( n − i − 1 2 ) − ( i − 1 2 + 1 ) = n − ( i − 1 ) − 1 = n − i \begin{aligned} &\quad \ \textit{arr}[i]-\textit{arr}[i-1] \\ &= \Big(n-\dfrac{i-1}{2}\Big)-\Big(\dfrac{i-1}{2}+1\Big) \\ &= n-(i-1)-1 \\ &= n-i \end{aligned} ​ arr[i]−arr[i−1]=(n−2i−1​)−(2i−1​+1)=n−(i−1)−1=n−i​

  • 当 i i i 是偶数时:

  arr [ i − 1 ] − arr [ i ] = ( n − i − 2 2 ) − ( i 2 + 1 ) = n − ( i 2 − 1 ) − i 2 − 1 = n − i 2 + 1 − i 2 − 1 = n − i \begin{aligned} &\quad \ \textit{arr}[i-1]-\textit{arr}[i] \\ &= \Big(n-\dfrac{i-2}{2}\Big)-\Big(\dfrac{i}{2}+1\Big) \\ &= n-\Big(\dfrac{i}{2}-1\Big)-\dfrac{i}{2}-1 \\ &= n-\dfrac{i}{2}+1-\dfrac{i}{2}-1 \\ &= n-i \end{aligned} ​ arr[i−1]−arr[i]=(n−2i−2​)−(2i​+1)=n−(2i​−1)−2i​−1=n−2i​+1−2i​−1=n−i​

由于 1 ≤ i < n 1 \le i < n 1≤i<n,因此 1 ≤ n − i ≤ n − 1 1 \le n-i \le n-1 1≤n−i≤n−1, arr \textit{arr} arr 对应的「相邻绝对差列表」中的元素各不相同,分别为 n − 1 n-1 n−1 到 1 1 1。

代码

class Solution {
    public int[] constructArray(int n, int k) {
        int[] answer = new int[n];
        int low = 1, high = k + 1;
        for (int i = 0; i <= k; i++) {
            if (i % 2 == 0) {
                answer[i] = low++;
            } else {
                answer[i] = high--;
            }
        }
        for (int i = k + 1; i < n; i++) {
            answer[i] = i + 1;
        }
        return answer;
    }
}

复杂度分析

  • 时间复杂度: O ( n ) O(n) O(n)。构造数组 answer \textit{answer} answer 的过程为遍历该数组一次,填入每个元素的时间为 O ( 1 ) O(1) O(1),因此时间复杂度为 O ( n ) O(n) O(n)。

  • 空间复杂度: O ( 1 ) O(1) O(1)。除了返回值以外,使用的空间复杂度是常数。

上一篇:【LeetCode】LCP 01. 猜数字(C++)


下一篇:【Python 第7课】if的介绍和使用