C 通过执行整数加法,在未排序的整数数组中查找目标值

C 通过执行整数加法,在未排序的整数数组中查找目标值,c,algorithm,optimization,C,Algorithm,Optimization,以下是“亚马逊”向我提出的一个采访问题。我还没有想出一个优化的解决方案 问题陈述: 给定一个未排序的整数数组n如果该数组中任何整数的加法与目标值匹配,则返回“true”,否则返回false 注意: 1)'n' could be 1000 or 10,000. 2) Target value could be 'negative' 3) It may be addition of any 'k' integers (not only two) , where k<=n.

以下是“亚马逊”向我提出的一个采访问题。我还没有想出一个优化的解决方案

问题陈述:
给定一个未排序的整数数组n如果该数组中任何整数的加法与目标值匹配,则返回“true”,否则返回false

注意:

   1)'n' could be 1000 or 10,000.
   2) Target value could be 'negative'
   3) It may be addition of any 'k' integers (not only two) , where k<=n.  
如果我们尝试线性地或正常地进行,则需要O(2^n)时间复杂度
因此,我正在寻找任何方法或算法,将优化这个问题更多


提前谢谢你

注意这个答案仍然信息丰富,所以我保留它,但在OP编辑之后,它就不那么相关了

下面是我将如何在
O(n)
运行时复杂性和
O(n)
空间复杂性中使用一个称为“哈希”的概念来解决它。(其中n是数组的大小)

让我们拨打我想要的电话号码
d

首先,我将创建某种类型的
哈希表
(键值存储)。 hashmap有
O(1)
insert、get和contains。你可以读到他们

然后,我将把单元格d-object中的每个对象都放在哈希映射中。在检查下一个数字x之前,我要检查哈希映射是否包含单元格x处的值。如果是这样,我们就找到了对手

下面是一些伪代码(我认为这是一个比C代码更好的通用答案)

CheckIfTwoNumbersComplementTo(d,arr)

map如何对数组进行排序,并为每个元素计算目标值所需的对并搜索它?这将使排序的成本加上每次二进制搜索。

子集和问题是一个众所周知的NP完全问题。在这里,我假设您正在寻找任何一组数字来求和到目标(如果您实际上只寻找两个数字,那么有一个五行的解决方案,使用一个在O(n)时间内运行的计数哈希表)

有两种基本方法。第一个就是测试每个可能的子序列。正如您已经观察到的,这需要O(2n)时间(指数),如果n为1000,这是很难解决的

第二种方法是跟踪从列表的前缀中可以获得的总和。这是一种非常简单的方法,如果整数是有界的,则效果很好。举例来说,如果输入是n个k位整数,则其计算复杂度为O(2kn2)(伪多项式):求和所能得到的最大值为2kn,因此该表最多有2kn2个条目。这是一种典型的动态规划方法,其中子问题是
T[s][k]=(a[1..k]有一个到s的子序列求和)
,最终的解由
T[target][n]
给出

下面是一个Python解决方案,它实现了以下功能:

def subset_sum(A, target):
    T = {0} # T[s][0] = (TRUE iff s == 0)
    for i in A:
        T |= {x + i for x in T}
    return target in T
示例:

>>> subset_sum([-5,6,7,1,0,12,5,-6,100], 13)
True
>>> subset_sum([95, -120, 22, 14491], 13)
False
>>> pair_sum([3,3,3,4], 13)
False
>>> pair_sum([3,3,3,10], 13)
True
>>> pair_sum([7,7,2], 14)
True
>>> pair_sum([7,14,2], 14)
False

奖励:如果你好奇,这里有一个解决配对和问题的方法。它以O(n)时间运行,并告诉您数组中是否有两个数字与目标求和

from collections import Counter
def pair_sum(A, t):
    C = Counter(A)
    for k,v in C.iteritems():
        if t == k+k and v > 1: return True # k is in the array twice
        elif t != k+k and t-k in C: return True
    return False
示例:

>>> subset_sum([-5,6,7,1,0,12,5,-6,100], 13)
True
>>> subset_sum([95, -120, 22, 14491], 13)
False
>>> pair_sum([3,3,3,4], 13)
False
>>> pair_sum([3,3,3,10], 13)
True
>>> pair_sum([7,7,2], 14)
True
>>> pair_sum([7,14,2], 14)
False

“任意两个整数的加法”是什么意思?或者任何数字?如果我没听错的话,你被要求解决这个问题,这是NP完全问题。因此,我们不能合理地期望你比指数时间或伪多项式时间做得更好。如果它是一对整数,我想你指的是O(n^2)时间,而不是O(2^n)。遗憾的是,只有两个人理解这样一个明确的问题。除了@nneonneo和kasavbere,其他人都离我们很远。人们还会读问题吗?或者他们只是认为他们知道的更多?@KarthikT No。这可能是“k”数的加法,其中k很好,但我打赌您的哈希表将占用超过O(n)的空间。为了获得有效的常量时间操作,您需要为许多哈希桶分配空间,不是吗?我的哈希表可以在O(n)空间中实现。我可以简单地分配一个大小为[n]的数组,并将索引直接用作键:)我不想在回答中特别建议,因为我想让解决方案尽可能通用。只有将问题更正为:“…如果/2/整数相加…”时,这才有效。而且,确切地说
O(n)
没有任何意义,你是说确切地说
n
空间吗?但从你自己的例子来看,这显然是错误的。数组允许重复,所以假设我们要求和1000,我们有一个1000的数组
1
s。与您的方案发生了疯狂的冲突(在这种情况下,算法也不起作用,因为它不再是求两个整数的和来找到给定的值)。我的意思是n个空间和n个台阶。当我得到一个副本的时候,我已经做了,所以我不关心副本。我不明白为什么我应该关心副本,我真的不需要存储-一百万次,我会编辑我的答案来澄清,尽管这是一个好的观点。所以那将是O(n log n)时间。