检查2个数组是否与I相加

min*_*ree 7 algorithm

我看到一个面试问题如下:给出一个未排序的整数数组A和一个整数I,找出A的任何两个成员是否加起来我.

任何线索?

时间复杂度应该更少

小智 22

将元素插入哈希表.

插入时x,检查是否I-x已存在.O(n)预计时间.

否则,将数组升序排序(从索引0到n-1).有两个指针,一个是最大值,一个是最小值(分别称为M和m).

If a[M] + a[m] > I then M-- 
If a[M] + a[m] < I then m++
If a[M] + a[m] == I you have found it
If m > M, no such numbers exist.
Run Code Online (Sandbox Code Playgroud)

  • @yankee:你能告诉我一个库的名称,它有一个现有的实用的哈希表实现,每次产生相同的哈希值吗? (2认同)

Las*_*olt 8

如果您具有整数所在的范围,则可以使用计数排序式解决方案,在该解决方案中扫描数组并计算数组.你有整数

input = [0,1,5,2,6,4,2]
Run Code Online (Sandbox Code Playgroud)

你创建一个像这样的数组:

count = int[7]
Run Code Online (Sandbox Code Playgroud)

其中(在Java中,C#等)适用于计算0到6之间的整数.

foreach integer in input
    count[i] = count[i] + 1
Run Code Online (Sandbox Code Playgroud)

这将为您提供阵列[1,1,2,0,1,1,1].现在,你可以扫描在这个阵列(的一半),并检查是否有整数加起来到i喜欢

for j = 0 to count.length - 1
    if count[j] != 0 and count[i - j] != 0 then // Check for array out-of-bounds here
         WUHUU! the integers j and i - j adds up
Run Code Online (Sandbox Code Playgroud)

总的来说,这个算法给出了O(n + k)n在长度为n的输入上扫描的位置,k是在长度为k的计数数组上的扫描(0和k-1之间的整数).这意味着如果n > k那时你有一个有保障的O(n)解决方案.


Gab*_*aru 7

  1. 对数组进行排序
  2. 每个元素XA,执行对二进制搜索I-X.如果I-XA,我们有一个解决方案.

这是O(nlogn).

如果A包含给定(足够小)范围内的整数,我们可以使用技巧来实现O(n):

  1. 我们有一个数组V.对于每一个元素XA,我们增加V[X].
  2. 当我们增加V[X]我们还要检查是否V[I-X]>0.如果是,我们有一个解决方案.

  • @Dan:你不能这样做,因为列表中可能有负整数.负整数+整数>我可以加上ti I. (3认同)

YOU*_*YOU 7

例如,循环并添加可能的数字来设置或散列,如果找到,只需返回它.

>>> A = [11,3,2,9,12,15]
>>> I = 14
>>> S = set()
>>> for x in A:
...     if x in S:
...         print I-x, x
...     S.add(I-x)
...
11 3
2 12
>>>
Run Code Online (Sandbox Code Playgroud)

  • 这是O(n).S中的x是O(1),S.add(Ix)是O(1),最坏的情况是O(n) - https://wiki.python.org/moin/TimeComplexity (2认同)