给定一个排序数组,输出所有三元组<a,b,c>,使得a-b = c </a,b,c>

时间:2011-08-23 18:00:45

标签: c algorithm

给定一个排序数组,输出所有三元组,使得a-b = c。 我到目前为止尝试的代码如下:但是有以下测试用例 -

-12 = -7 - 5
-12 =  3 - 15
 -7 = -4 - 3
 -7 =  3 - 10
 -7 =  9 - 16
 -4 =  5 - 9
  3 = -4 - -7
  5 = -7 - -12
  5 = 15 - 10 
 10 = 3 - -7 
 10 = 15 - 5
15 = 3 - (-12)
16 = 9 - (-7)

虽然我的程序仅打印 -

-12 = -7 - 5
 -7 = -4 - 3
 -12 = 3 - 15
 -7 = 3 - 10
 -4 = 5 - 9
 -7 = 9 - 16
 5 = 15 - 10

仅表示绝对差异!任何建议都会有很大的帮助!

void binder(int*a, int n) {
    int i;
  for (i = 0; i < n; i++) {
    int current = a[i];
    int left = 0;
    int right = n-1;
    while (left < right) {
      if ( left == i ) {
        left++;
        continue;
      }


if (right == i) {
        right--;
        continue;
      }



if (a[left] + a[right] < current) {
        left++;
      } else if (a[left] + a[right] > current) {
        right--;
      } else {
        printf("\n %d = %d - %d",a[left],current, a[right]);
        left++;
        right--;
      }
    }
  }
}



int main() {
  int a[] = {-12, -7, -4, 0, 3, 5, 9, 10, 15, 16};
  binder(a, 10);
  return 0;
}

5 个答案:

答案 0 :(得分:1)

似乎测试用例也缺少三元组:

9 =  5 - (-4)

尝试更改您的打印:

printf("\n %d = %d - %d",a[left],current, a[right]);

为:

printf("\n %d = %d - %d",a[left],current, a[right]);
printf("\n %d = %d - %d",a[right],current, a[left]);

答案 1 :(得分:1)

这个解决方案是O(n ^ 3),但它应该可以工作。

void binder(int*a, int n)
{
    for(int left = 0; left < n; left++)
    {
        for(int right = 0; right < n; right++)
        {
            for(int result = 0; result < n; result++)
            {
                if(left != right && left != result && result != right && a[left] - a[right] == a[result])
                    printf("\n %d = %d - %d", a[result], a[left], a[right]);
            }
        }
    }
}

答案 2 :(得分:1)

如果它们被排序,(并且正如Hanning指出的那样,ab = c与a = b + c相同),你可以从最小的b和c开始,并添加它们,这应该导致最小的a 。现在在增加b或c的同时,a也只能变大,所以你应该永远不要回头。

如果你制作一个b和c的表及其总和(应该是a的一个):

c\ b:-12    3   4   5   7  10  15 16  
-12: -24, -19, -9, -7, -3, -2,  3, 4
 -7:  -9,  -4,  6,  8, 12, 13, 18, 
  3:  -8,  -3,  7,  9, 13, 14, 19, 
  5:  -7,  -2,  8, 10, 14, 15, 
  9:  -5,   0, 10, 12, 16, 
 10:  -2,   3, 13, 15,  
 15:   3,   8, 18,  
 16:   4,   9, 19,  

你看,我省略了右下角的值,因为之前的值(左起)已经超过了最大值a(15),所以更高的值无法匹配。

当然,对于这么少的方程式,你会比在多余的多余计算中获得更多的时间来考虑优化。对于更大的值集,优化可能是有用的。

答案 3 :(得分:1)

这样的事情怎么样:

HashTable table;
for b = 0 to n-1:
    for c = 0 to n-1:
        table[b + c] = <b, c>
    end for
end for

for a = 0 to n-1:
    if table[a] exists and (<b, c> in table[a] where b != a and c != a) then:
        output <a, b, c>
    end if
end for

因此,如果我们考虑“a = b + c”,对于每个(b,c)值对,我们将其放在哈希表中,将其与(b,c)对关联[O(n ^ n ^ 2)]。

然后,我们再次遍历数组,如果哈希表中出现一个值,并且关联的对用于不同的索引,那么我们找到了一个新条目(将条款重新排列为“ab = c”) 。该步骤为O(n),总体上产生O(n ^ 2)解。

我认为我们可以将这个问题看作是“找到一个数组中的值对,总结为S,对于一个固定的S”问题的变体。

答案 4 :(得分:0)

您错过了代码中的一个迭代/循环。因为你正在使用蛮力策略,所以分析说它需要O(n ^ 3)空间,你编码的时间复杂度似乎是O(n ^ 2)。 这是帮助您理解的案例。 你检查: a = b-c 你跳过检查: c = b-a