寻找最接近的数对(挑战)智能解析AI算法| 豆包MarsCode AI刷题

141 阅读3分钟

本篇文章深入探讨如何在一个整数数组中找到差值最小的数对,并提供了两种解决方案。方法一是排序加扫描,时间复杂度约为 O(n log n);方法二是利用堆,时间复杂度为 O(n log k)。文中详细分析了两种方法的时间复杂度,并展示了可视化对比,当数组规模达到 5000 时,方法二略优于方法一。附有代码实现和测试用例。

关联问题: 如何优化堆运算 能否简化排序过程 不同排序算法之间的比较 基于该文章继续向AI提问

问题描述

给你一个数组 nums 和一个整数 k,请你返回该数组中差值最小的 k 对数对。输出的结果需要按升序排列。

你的算法设计时间复杂度应优于 O(n^2),其中 n 是数组大小。

输入

nums: 一个整数数组 k: 一个整数

返回

返回一个包含 k 对数对的字符串,每对数对以小括号格式表示,数对之间用逗号分隔。每对数对中的两个数按升序排列。

参数限制

1 <= nums[i] <= 10^4 1 <= nums.length <= 10^5 k 的取值范围是 [1, 数对总数] 题目数据保证答案唯一,即数组中满足条件的 k 对数对是唯一的

测试样例

样例1:

输入:nums = [1, 3, 6, 9], k = 2 输出:"(1,3),(3,6)" 解释:此时差值最小的数对为 (1, 3) 和 (3, 6)。

样例2:

输入:nums = [2, 5, 7, 11], k = 1 输出:"(5,7)"

样例3:

输入:nums = [8, 15, 19, 23], k = 3 输出:"(8,15),(15,19),(19,23)"

方法一:排序加扫描

def find_closest_pairs(nums, k): # 先对数组进行排序 nums.sort()

# 定义一个列表存储差值最小的数对
differences = [(abs(nums[i] - nums[i + 1]), (nums[i], nums[i + 1])) for i in range(len(nums) - 1)]

# 按差值进行排序
differences.sort(key=lambda x: x[0])

# 提取前k个数对
smallest_pairs = [pair for _, pair in differences[:k]]

# 转换成字符串格式并返回
return ','.join(f'({a},{b})' for a, b in smallest_pairs)

算法步骤:

  • 首先,将数组进行排序,时间复杂度为 O(n log n)。
  • 计算相邻元素之间的差值并记录数对,时间复杂度为 O(n)。
  • 对差值进行排序,并提取差值最小的 k 对数对,时间复杂度为 O(n log n)。
  • 结果转换成字符串格式输出。

方法二:堆排序思想

def find_closest_pairs(nums, k): import heapq

# 先对数组进行排序
nums.sort()

# 定义一个最小堆存储数对和它们的差值
min_heap = []

for i in range(len(nums) - 1):
    # 计算差值并加入最小堆
    diff = abs(nums[i] - nums[i + 1])
    heapq.heappush(min_heap, (diff, nums[i], nums[i + 1]))

# 提取堆中的前 k 个最小差值数对
smallest_pairs = [heapq.heappop(min_heap)[1:] for _ in range(k)]

# 转换成字符串格式并返回
return ','.join(f'({a},{b})' for a, b in smallest_pairs)

算法步骤:

  • 先对数组排序,时间复杂度为 O(n log n)。
  • 计算相邻元素差值,使用堆记录差值和数对,时间复杂度为 O(n log k)。
  • 从堆中提取前 k 个最小差值数对,时间复杂度为 O(k log n)。
  • 组合成字符串格式输出。