为什么我的采访算法是次优的方法?

时间:2017-11-29 04:57:03

标签: python algorithm subset-sum

  

给定一个整数列表l = [1,5,3,2,6]和一个目标t = 6,如果列表包含两个与目标相加的不同整数,则返回true

我在Python技术面试中得到了这个问题,导致我不能通过。我的回答是:

def two_Sum(l, target):
  for num in l:
    for secondNum in l:
      if num != secondNum:
        if num + secondNum == target:
          return True

我给出的反馈是我的解决方案是"不是最佳的"。请帮助我理解为什么这不是最佳解决方案,并详细解释这个案例的最佳选择!

4 个答案:

答案 0 :(得分:3)

你的解决方案有一个嵌套循环迭代列表,这意味着它是 O(n ^ 2)时间复杂度 - 和 O(1)空间,因为你不在迭代期间需要存储任何数据。

这样可以降低到 O(n)时间复杂度,代价是增加到O(n)空间复杂度:

def two_sum(l, target):
    s = set(l)
    for n in l:
        delta = target - n
        if delta != n and delta in s:
            return True
    return False

稍微改进一下,你甚至可以避免遍历整个列表,但它仍然是 O(n)

def two_sum(l, target):
    seen = set()
    for n in l:
        delta = target - n
        if delta != n and delta in seen:
            return True
        seen.add(n)
    return False

答案 1 :(得分:1)

你可以从两个指针(开始,结束)开始,start将指向列表的开头,end将指向列表的结尾,然后添加它们并查看它是否等于你的目标,如果等于则打印或添加到结果。

如果sum大于你的目标,那意味着将你的结束指针减少1,如果它等于或小于你的目标,那么增加你的开始指针。

def two_Sum(l,target):
    start=0
    end=len(l)-1
    while start!=end:
        pair_sum=l[start]+l[end]
        if pair_sum==target:
            print l[start],l[end]

        if pair_sum <= target:
            start=start+1

        if pair_sum > target:
            end = end-1


l=[1,2,3,4,5,6,7,8,9,10]


two_Sum(l,9)

答案 2 :(得分:0)

最有效的方法是为每个i散列T-I [i]并检查每个元素

def sum2(I,T):
   h = {}
   for itm in I:
      if itm in h:
          return True
      h[T-itm] = 1
   return False

答案 3 :(得分:-1)

您的解决方案是O(n²),因为您对整个列表进行了嵌套迭代。

时间复杂度为n log(n)的简单解决方案是:

  • 对您的列表进行排序
  • 迭代对target
  • 的补充进行二进制搜索

假设您在函数bs(item, sorted_list)中实现了二进制搜索:

def two_Sum(l, target):
    l_sorted = sorted(l)  # n log(n)
    return any(bs(target - x, l_sorted) for x in l_sorted)  # n log(n)

如果到达target/2,您还可以执行其他一些优化,例如停止迭代。

警告:我不保证也不相信这是 最佳解决方案,而是旨在向您展示一个更好的解决方案,并为您的改进提供洞察力。