伴学笔记 数组重排最小化差值 | 豆包MarsCode AI刷题

3 阅读4分钟

一、题目背景与解析

问题描述
小C 和小U 面临一个优化问题,需要通过重新排列数组 a 的元素,来使数组 a 和数组 b 之间的差异最小化,计算目标是:

sum(abs(a[i]b[i]))sum(abs(a[i]b[i]))sum(abs(a[i]b[i]))sum(abs(a[i]−b[i]))\text{sum}(\text{abs}(a[i] - b[i]))sum(abs(a[i]−b[i]))

其中,ab 长度相同。为达到这一目标,需要找到最优的排列方式。


二、思路分析

1. 数组排列对最小化绝对值之和的影响:
重新排列数组 a 的元素意味着可以任意调整其顺序,以使每个元素与数组 b 中对应位置的元素尽可能接近。显然:

  • ab 排序后,按顺序一一对应配对是最优的排列方式。
  • 因为排序后,两数组的元素分布更接近,逐个相减后差值最小。

2. 为什么排序是最优解?
假设数组未排序,我们随机选择某些元素重新配对,可能会造成一个大的绝对差值。这种不匹配会显著增加总和。例如:

  • a = [1, 9, 6]b = [2, 5, 7],通过排序配对 [1, 2], [6, 5], [9, 7] 可达到最优;
  • 若随机配对 [1, 5], [9, 2], [6, 7],结果显然差值更大。

因此,按升序排列后配对的策略是最佳。


三、代码实现与解释

python

def solution(a: list, b: list) -> int:
    # 先对两个数组进行排序
    a.sort()
    b.sort()
    
    # 计算所有元素差值的绝对值之和
    return sum(abs(ai - bi) for ai, bi in zip(a, b))

if __name__ == '__main__':
    print(solution([2, 1, 3, 2], [5, 2, 4, 2]) == 5)
    print(solution([1, 4, 6], [2, 5, 7]) == 3)
    print(solution([1, 9, 6], [2, 5, 7]) == 4)

代码分析:

  1. 排序:

    • 调用 Python 的内置排序函数 sort() 对两个数组升序排列,时间复杂度为 O(nlog⁡n)O(n \log n)O(nlogn)。
  2. 绝对值计算:

    • 使用列表压缩和内置 zip() 函数,将两个数组排序后对应的元素逐个计算差值绝对值。
    • 利用 sum() 函数对绝对值求和,时间复杂度为 O(n)O(n)O(n)。

四、测试用例与结果

测试用例1:
输入:a = [2, 1, 3, 2]b = [5, 2, 4, 2]

  • 排序后:a = [1, 2, 2, 3]b = [2, 2, 4, 5]
  • 配对差值:abs(1-2) + abs(2-2) + abs(2-4) + abs(3-5) = 1 + 0 + 2 + 2 = 5
    输出:5

测试用例2:
输入:a = [1, 4, 6]b = [2, 5, 7]

  • 排序后:a = [1, 4, 6]b = [2, 5, 7]
  • 配对差值:abs(1-2) + abs(4-5) + abs(6-7) = 1 + 1 + 1 = 3
    输出:3

测试用例3:
输入:a = [1, 9, 6]b = [2, 5, 7]

  • 排序后:a = [1, 6, 9]b = [2, 5, 7]
  • 配对差值:abs(1-2) + abs(6-5) + abs(9-7) = 1 + 1 + 2 = 4
    输出:4

五、知识总结与个人思考

1. 排序的作用:
排序是解决很多优化问题的基础思路之一,尤其是类似“最小化”和“最大化”的问题。排序后,元素之间的“距离”变得更具规律性,便于通过一对一的分配实现目标。

2. 贪心策略的适用性:
本题中,通过排序后直接逐对计算绝对值,是一种贪心策略的体现。在每一步都选择最小的绝对差值,确保全局最优。

3. 代码的通用性:
该解决方案具有高度通用性,适用于数组长度相同且需要最小化差值的问题。对于更复杂的情况,如不同长度的数组,可以考虑动态规划的优化方案。

个人反思:

  • 这道题虽然看似简单,但充分体现了算法设计中的“局部最优”与“全局最优”关系。排序的思维不仅提升了效率,也简化了问题的复杂度。
  • 在实际应用中,类似问题可以扩展到“任务分配”、“资源调度”等场景。

六、学习计划与建议

  1. 学习目标:

    • 继续强化对排序算法的理解,掌握快速排序、归并排序等常用算法的原理与实现。
    • 深入学习贪心算法的基本思想与应用场景。
  2. 实践建议:

    • 尝试解决更多涉及“最小化差值”的问题,如最小生成树、区间覆盖等。
    • 探索动态规划方法对类似问题的解法,体会不同算法思路的异同。

七、总结

本题通过排序结合逐对计算绝对值的方法,利用贪心策略高效解决了数组重排最小化差值的问题。它展示了算法设计中“局部最优策略”的力量,同时为解决更多优化类问题提供了思路。希望这份笔记能帮助大家深入理解问题的本质,并为类似问题提供参考!