具有O(n ^ 2)算法用于"二和",转换为O(n)线性解

时间:2017-04-16 20:06:34

标签: algorithm big-o

我对经典的两和问题有一个O(n ^ 2)解。其中A [1 ... n]排序正整数数组。 t是一些正整数。

需要表明A包含两个不同的元素a和b s.t. a + b = t

到目前为止,这是我的解决方案:

t = a number;
    for (i=0; i<A.length; i++)
          for each A[j]
            if A[i] + A[j] == t
                return true
    return false

如何使其成为线性解决方案? O(n)试图弄清楚我的头脑。

到目前为止,这是我想到的一种方法。我将在A的开头开始,j将在A的结尾开始。我将增加,j将减少。所以我在for循环中有两个计数器变量,i&amp;学家

3 个答案:

答案 0 :(得分:2)

有很多方法可以改进。

  1. 您可以扩展您的算法,但不是对每个术语进行简单搜索,而是可以进行二进制搜索
  2. t = a number
    for (i = 0; i < A.length; i++)
      j = binarySearch(A, t - A[i], i, A.length - 1)
      if (j != null) 
          return true
    return false
    

    二进制搜索是通过O(log N)步骤完成的,因为你对数组中的每个元素执行二进制搜索,整个算法的复杂性将是O(N * log N) 这已经是对O(N ^ 2)的巨大改进,但你可以做得更好。

    1. 我们以和11和数组1,3,4,8,9为例。 你已经可以看到(3,8)满足总和。为了找到它,想象有两个指针,一旦指向数组的开头(1),我们将其称为H并用粗体表示它,另一个指向数组的末尾( 9),我们称之为T并用强调表示它。
    2. 1 3 4 8 9

      现在两个指针的总和是1 + 9 = 10。 10小于所需的和(11),没有办法通过移动T指针达到所需的总和,所以我们将H指针向右移动:

      1 3 4 8 9

      3 + 9 = 12大于所需的总和,没有办法通过移动H指针达到所需的总和,向右移动将进一步增加总和,向左移动它将我们带到初始状态,所以我们将T指针向左移动:

      1 3 4 8 9

      3 + 8 = 11&lt; - 这是所需的总和,我们已经完成了。

      因此算法的规则包括向左移动H指针或向右移动T指针,当两个指针的总和等于所需的总和,或者H和T交叉时,我们就完成了(T变小了比H)。

      t = a number
      H = 0
      T = A.length - 1
      S = -1
      
      while H < T && S != t
          S = A[H] + A[T]
          if S < t
              H++
          else if S > t
              T--
      
      return S == t
      

      很容易看出这个算法在O(N)运行,因为我们最多遍历每个元素一次。

答案 1 :(得分:0)

你创建了2个包含索引0和索引n-1的新变量,让我们分别称它们为i和j。 然后,检查A [i]和A [j]的总和,如果和小于t,则增加i(较低的索引),如果它大,则减小j(较高的索引)。继续,直到你找到i和j这样A [i] + A [j] = t所以你返回true,或者j&lt; = i,你返回false。

int i = 0, j = n-1;
while(i < j) {
    if(A[i] + A[j] == t)
        return true;
    if(A[i] + A[j] < t)
        i++;
    else
        j--;
return false;

答案 2 :(得分:0)

鉴于A [i]相对较小(可能小于10 ^ 6),您可以创建一个大小为10 ^ 6的数组B,每个值等于0.然后应用以下算法:

for i in 1...N:
    B[A[i]] += 1
for i in 1...N:
    if t - A[i] > 0:
        if B[t-A[i]] > 0:
            return True

编辑:好吧,既然我们知道数组已经排序,那么找到另一种算法可能会更明智。我会在这里留下答案,因为它仍适用于某类相关问题。