LeetCode 932. 漂亮数组
题目描述

题意分析
构造
1到n的一个排列,使任意i<k<j都满足2*A[k] != A[i]+A[j]。限制针对任意跨度的三个位置,不只是相邻元素;只要给出一个合法排列即可。直接逐个选择元素很难维护所有三元组约束,可以从较小的合法数组出发,用保持这个性质的变换不断扩大。
解法:分治构造(奇数部分 + 偶数部分)
核心思路
[!blue]
先把所有奇数排成连续一块,再把所有偶数排成连续一块。对任意左右端点,若它们属于不同块,数值之和为奇数,不可能等于某个整数的两倍;若属于同一块,中间下标也一定在该块内。因此只要每块内部合法,拼接后整个数组就合法。
若旧数组已经漂亮,把每个值
x同时换成2x-1,得到的奇数块仍然漂亮:新数组若出现等式,将两边的倍数与常数消去,就会得到旧数组中同样的等差等式,与假设矛盾。偶数映射2x也同理。两次映射都保留旧元素的相对顺序,所以可以直接作为两块内部的排列。从只有一个元素的
[1]开始,每轮按旧顺序生成全部奇数,再生成全部偶数,并丢弃超过n的值。删除元素只会保留原顺序中的部分位置;若剩下的元素出现违规三元组,它在删除前也已经存在,因此过滤不会破坏漂亮性。还要保证结果确实是完整排列。若旧数组恰好包含
1..m各一次,奇数与偶数映射分别覆盖1..2m中的奇数和偶数,块内没有重复,两块也不相交;过滤后恰好得到1..min(2m,n)。所以元素数量逐轮翻倍,最后达到n,既不漏数也不重复,构造一定结束。
解题步骤
- 以 [1] 为构造起点。
- 按旧顺序生成不超过 n 的所有 2x-1。
- 再按旧顺序生成不超过 n 的所有 2x。
- 替换为新数组,直到包含 n 个数。
n=1时初始数组已经是答案。其余情况下每轮都必须完整生成奇数块后再生成偶数块,不能把两种映射交替写入,否则跨块端点的奇偶证明就不再适用。
代码实现
class Solution {
public int[] beautifulArray(int n) {
List<Integer> res = new ArrayList<>();
res.add(1);
while (res.size() < n) {
List<Integer> tmp = new ArrayList<>(n);
for (int x : res) {
// 先按原顺序生成整块奇数,仿射变换保持原有漂亮性。
int v = 2 * x - 1;
if (v <= n) {
tmp.add(v);
}
}
for (int x : res) {
// 再生成整块偶数,跨块端点一奇一偶,不会形成整数平均。
int v = 2 * x;
if (v <= n) {
tmp.add(v);
}
}
res = tmp;
}
int[] answer = new int[n];
for (int i = 0; i < n; i++) {
answer[i] = res.get(i);
}
return answer;
}
}
func beautifulArray(n int) []int {
res := []int{
1,
}
for len(res) < n {
tmp := make([]int, 0, n)
for _, x := range res {
// 先按原顺序生成整块奇数,仿射变换保持原有漂亮性。
v := 2*x - 1
if v <= n {
tmp = append(tmp, v)
}
}
for _, x := range res {
// 再生成整块偶数,跨块端点一奇一偶,不会形成整数平均。
v := 2 * x
if v <= n {
tmp = append(tmp, v)
}
}
res = tmp
}
return res
}
复杂度分析
- 时间复杂度:各轮有效长度按倍数增长,映射扫描总量为 $O(n)$;当前实现每轮都预分配容量
n,共有 $O(\log(n+1))$ 轮,计入分配初始化后的上界为 $O(n\log(n+1))$。- 空间复杂度:$O(n)$,同时保存前后两轮数组。
关键点总结
[!green]
- 奇偶分块负责消除跨块冲突,保持等差关系的映射负责保证块内合法。
- 覆盖范围每轮从
1..m扩大到1..min(2m,n),保证构造完整且终止。- 过滤只删除元素并保留顺序,不会产生新的违规三元组。
易错点总结
[!yellow]
- 不能只保证所有值互不相同,还要保持奇偶连续分块和块内原有顺序。
- 奇数映射必须是
2x-1,写成2x+1会漏掉数字1。- 生成时过滤大于
n的值,长度达到n后立即结束。
相似题目
| 题目 | 难度 | 关联与区别 |
|---|---|---|
| 1968. 构造元素不等于两相邻元素平均值的数组 | 中等 | 原题只禁止相邻三项出现中间等于两侧平均,本题禁止任意跨度的三项,需更强的奇偶分治构造。 |
转载与许可
许可
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处!