这是 2Sum 问题的推广
给定一个未排序的数字数组,您如何找到总和最接近任意目标的一对数字。请注意,可能不存在完全匹配,因此 O(n)
哈希表解决方案不适合此处。
对于目标 0,我可以在 O(n*log(n))
时间内解决问题:
按绝对值对数字进行排序。
遍历排序数组,保持相邻值之和的最小值。
之所以可行,是因为对(+/+、+/-、-/-)的三种情况都由绝对值逻辑处理。即,同号对的和在最接近0时最小,异号对的和在对的分量最接近时最小。这两种情况在按绝对值排序时都有体现。
我如何将其概括为任意目标总和?
第一步:对数组进行非降序排序。复杂度:O( n lg n )
第二步:从两端向内扫描。复杂度:O(n)
在排序数组 A
上,让 l
指向最左边(即最小)元素,r
指向右边-大多数(即最大)元素。
while true:
curSum = A[ l ] + A[ r ]
diff = currSum - target
if( diff > 0 ):
r = r - 1
else:
l = l + 1
如果 diff == 0
,那么您就得到了 2Sum 的完美匹配。
否则,在 diff
中寻找符号的变化,即从正向负向或从负向正向的转变。每当转换发生时,无论是在更改之前还是之后,currSum
都最接近 target
。
整体复杂度:O( n log n ) 因为第 1 步。