装饰品丑陋值最小化问题求解 | 豆包MarsCode AI刷题

85 阅读2分钟

问题描述

小M在整理桌子上的装饰品时,发现高度差异过大的装饰品放在一起会显得不美观。她希望通过交换装饰品的位置,使得它们的高度变化更加平滑,从而最小化整体的丑陋值。装饰品的丑陋值定义为相邻装饰品高度差的绝对值之和。小M可以任意交换装饰品的位置,目标是找到一种装饰顺序,使得丑陋值达到最小。

例如:当三个装饰品的高度分别为 3, 1, 2 时,通过交换它们的顺序,可以将高度排列为 1, 2, 3,此时丑陋值为 |1-2| + |2-3| = 2,这是最优解。

测试样例

样例1:

输入:n = 3, a = [3, 1, 2]
输出:2

样例2:

输入:n = 5, a = [10, 20, 30, 5, 15]
输出:25

样例3:

输入:n = 4, a = [100, 200, 50, 150]
输出:150

问题解析

要解决这个问题,我们需要找到一种排列方式,使得相邻装饰品的高度差的绝对值之和最小。这里求解最小的丑陋值,实际上就是求解相邻数值间最小距离和。绘制数轴即可发现,顺序排列的距离和一定是最小距离和。

故而,只需将储存在列表a中的高度进行顺序排列,再根据丑陋值的定义,计算相邻数字间差值,即可求得最小丑陋值。

def solution(n: int, a: list) -> int:
    lis = sorted(a)  #按高度对装饰品进行顺序排列
    ugly = 0   #丑陋值
    #计算丑陋值之和
    for i in range(len(a) - 1):
        ugly += lis[i + 1] - lis[i]
    return ugly

此时代码运行后,测试样例输出均正确,再对代码进行进一步优化。

同样是利用数轴,任意选取n个数字按照顺序排列在数轴上,不难得出其相邻数字距离之和即为最小值和最大值的距离,也就是最小值与最大值之差

则此时代码可优化为

def solution(n: int, a: list) -> int:
    #将装饰品按高度进行顺序排列
    left = min(a)   #装饰品最小高度
    right = max(a)   #装饰品最大高度
    
    return right - left

同样测试正确。

总结

总的来说,这道问题并不复杂,在未看破其背后隐藏的数学规律前,也可以采用贪心算法来求解,但当我们运用可视化——利用数轴来总结规律时,就可以很好地避免掉相对复杂的处理方式,降低时间复杂度,直接发现问题规律来处理数据。