1968. 构造元素不等于两相邻元素平均值的数组

重新排列数组,使中间元素不等于两侧邻居平均值——题解分享


题目描述

给定一个下标从 0 开始的数组 nums,数组由若干互不相同的整数构成。我们需要对数组中的元素进行重新排列,使得重排后的数组满足以下条件:

对于数组中每个满足 1 <= i < nums.length - 1 的索引 i,元素 nums[i]不等于 其两侧相邻元素的平均值,即:

nums[i]≠nums[i−1]+nums[i+1]2nums[i] \neq \frac{nums[i-1] + nums[i+1]}{2}nums[i]=2nums[i1]+nums[i+1]

换句话说,不允许存在:

nums[i]×2=nums[i−1]+nums[i+1]nums[i] \times 2 = nums[i-1] + nums[i+1]nums[i]×2=nums[i1]+nums[i+1]


输入输出示例

示例 1:

输入:nums = [1, 2, 3, 4, 5]

输出:[1, 2, 4, 5, 3]

解释:

  • i=1, nums[1]=2,两相邻元素平均值为 (1+4)/2=2.5,不等于2
  • i=2, nums[2]=4,两相邻元素平均值为 (2+5)/2=3.5,不等于4
  • i=3, nums[3]=5,两相邻元素平均值为 (4+3)/2=3.5,不等于5

示例 2:

输入:nums = [6, 2, 0, 9, 7]

输出:[9, 7, 6, 2, 0]

解释:

  • i=1, nums[1]=7,两相邻元素平均值为 (9+6)/2=7.5,不等于7
  • i=2, nums[2]=6,两相邻元素平均值为 (7+2)/2=4.5,不等于6
  • i=3, nums[3]=2,两相邻元素平均值为 (6+0)/2=3,不等于2

解题分析

题目要求的条件看似复杂,但细心观察可以发现:

  • 关键在于避免某个元素正好是其左右邻居的“中点”。
  • 数组元素互不相同,这样避免了相邻相等的情况。
  • 重新排列数组后,让相邻元素的差距拉开,避免中间元素“恰巧”是邻居均值。

解决方案核心思想

排序+交错排列

  1. 先排序,让元素从小到大排列。
  2. 将排序后的数组分成两部分:
    • small:数组左半部分(较小元素)
    • large:数组右半部分(较大元素)
  3. 将两部分元素交替排列,形成一个新的数组。

举例说明:

对于数组 [1, 2, 3, 4, 5]

  • 排序后保持不变。
  • small = [1, 2, 3]
  • large = [4, 5]

交替排列后:

[1, 4, 2, 5, 3]

这样排列可以有效避免某元素等于左右邻居的平均值。


为什么交替排列可以满足条件?

交错排列确保了:

  • 较小元素被较大元素分隔,避免中间元素成为两侧的平均值。
  • 由于两组元素分别是升序排列,混合排列后的“跳跃”使得均值不可能刚好等于中间元素。
  • 在实际测试中,这种方法可满足题意。

代码实现示例(Python)

from typing import List

class Solution:
    def rearrangeArray(self, nums: List[int]) -> List[int]:
        nums.sort()
        n = len(nums)
        mid = (n + 1) // 2
        small = nums[:mid]
        large = nums[mid:]
        
        res = []
        # 交错合并 small 和 large
        for s, l in zip(small, large):
            res.append(s)
            res.append(l)
        # 如果 small 比 large 多一个元素,加入最后一个元素
        if len(small) > len(large):
            res.append(small[-1])
        
        return res

代码解析

  • nums.sort():排序数组。
  • mid = (n + 1) // 2:划分点,保证左半部分元素数量不小于右半部分。
  • small = nums[:mid]large = nums[mid:]:分割成两部分。
  • 通过 zip 交替合并两部分元素。
  • 如果左半部分多一个元素,最后补充进结果中。

复杂度分析

  • 时间复杂度:排序为主,O(n log n),合并过程为 O(n)
  • 空间复杂度:辅助数组 smalllargeO(n)

示例演示

假设输入 nums = [6, 2, 0, 9, 7]

  1. 排序后:[0, 2, 6, 7, 9]
  2. small = [0, 2, 6]
  3. large = [7, 9]
  4. 交替合并得到 [0, 7, 2, 9, 6]
  5. 检查中间元素:
    • i=1,7 != (0+2)/2=1
    • i=2,2 != (7+9)/2=8
    • i=3,9 != (2+6)/2=4
      满足条件。

方法优劣比较

方法时间复杂度实现难度适用场景备注
排序+交错排列O(n log n)数组元素互不相同,需重排结构简单,效果好,常用解法
其他贪心策略可能更复杂特殊情况,可能需要更复杂处理不推荐,易错且难以维护

总结

  • 该问题可以通过对数组排序后分成两半,再交错排列的策略轻松解决。
  • 这种排列避免了中间元素成为邻居元素平均值的情况。
  • 代码实现简洁且高效,适用于大规模数组。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值