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

时间:2013-02-01 03:40:44

标签: 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.  

测试条件:

    i/p:- Array A[]= {6,7,3,0,12,-5,-6,100}
    Target =  8
    o/p:- TRUE        
As, 6+7+(-5)=8

如果我们尝试线性或正常运行,则需要 O(2 ^ n)时间复杂度
所以我正在寻找能够更好地优化这个问题的任何方法或算法。

提前谢谢!

3 个答案:

答案 0 :(得分:9)

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

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

第二个是跟踪从列表的前缀可以获得的总和。这是一种非常简单的方法,如果整数有界,则效果很好。举例来说,如果输入是n个k位整数,则它具有计算复杂度O(2 k n 2 )(伪多项式):总和可以得到的最大值是2 k n,因此该表最多有2个 k n 2 条目。这是一种典型的动态编程方法,子问题为T[s][k] = (A[1..k] has a subsequence summing to 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

奖金:如果你很好奇,这里是配对问题的解决方案。它在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

示例:

>>> 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

答案 1 :(得分:1)

注意这个答案仍然是有用的,所以我保留了它,但在OP编辑之后,它的相关性较低。

以下是我如何使用名为'Hashing'的概念在O(n)运行时复杂度和O(n)空间复杂度中解决它。 (其中n是数组的大小)

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

首先,我会创建某种HashTable(一个键值存储)。 HashMaps有O(1) insert,get和contains。你可以阅读它们here

然后我会将每个对象放在哈希映射中的单元格d对象中。在我检查下一个数字x之前,我会检查哈希映射是否包含单元格x的值。如果确实如此,我们找到了匹配。

这是一些伪代码(我认为这对于一般答案比C代码更好)

CheckIfTwoNumbersComplementTo(d,arr)
    map <-- new HashTable
    for each number x in Arr
        if(map contains a key for x)
            return true
        else
            add d-x to map if it is not already in map
    return false

答案 2 :(得分:0)

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