查找具有给定差异的对

时间:2014-03-09 12:17:15

标签: algorithm

给定n,k和n个整数。你如何找到它们的差值为k的整数对?

有一个n*log n解决方案,但我无法理解。

3 个答案:

答案 0 :(得分:4)

你可以这样做:

  • 对数组进行排序
  • 对于每个项data[i],确定其两个目标对,即data[i]+kdata[i]-k
  • 对这两个目标的已排序数组运行二进制搜索;如果找到,请将data[i]data[targetPos]添加到输出中。

排序在O(n*log n)完成。每个n搜索步骤都需要2 * log n时间来查找目标,总时间为O(n*log n)

答案 1 :(得分:4)

对于这个问题,存在线性解决方案!问问自己一个问题。如果你有a数组中应该有多少个数字?当然a+ka-k(特殊情况:k = 0,需要另一种解决方案)。那么,现在呢?

  • 您正在使用数组中的所有值创建一个哈希集(例如,在C ++ 11中为unordered_set)。每个元素O(1) - Average complexity,因此 O(n)
  • 您正在遍历数组,并检查每个元素Is present in the array (x+k) or (x-k)?。你检查每个元素,在 O(1)中设置,你检查每个元素一次,所以它是线性 O(n) )。
  • 如果您找到x配对(x+k / x-k),那就是您要找的。

所以它是线性 O(n))。如果你真的想要 O(n lg n)你应该在树上使用一个集合,并在(lg n)中检查is_exist,那么你就 O(n lg n)算法。

合并:无需检查x+kx-k,只需x+k即可。因为如果ab配对良好,那么:

if a < b then
 a + k == b
else 
 b + k == a

改进:如果您知道某个范围,则可以使用bool表(set_tab[i] == true,当i在表格中时)来保证线性复杂性。)

答案 2 :(得分:3)

与上述类似的解决方案:

  1. 对数组进行排序
  2. 设置变量i = 0; j = 1;
  3. 检查array[i]array[j]
  4. 之间的区别
    • 如果差异太小,请增加j
    • 如果差异太大,请增加i
    • 如果您要查找的是差异,请将其添加到结果中并增加j
  5. 重复3和4直到数组结束
  6. 排序为O(n*lg n),下一步是,如果我是正确的,O(n)(最多2 * n次比较),那么整个算法为O(n*lg n)