Вот классное решение на С (++)
int a[3], b[3]; /* the two arrays */
int c[4]; /* target */
int s=0, t=0, k;
int i;
for (i=0;i<3;i++) { k = a[i]-b[i]; s += k; t += k*(a[i]+b[i]); }
/* At this point s is the difference of the two distinct elements
and t is the difference of their squares, i.e. s = x - y and t = x^2 - y^2
because (x-y)(x+y) = x^2-yx+yx-y^2 = x^2-y^2
Because the two elements are distinct, s != 0 and we can easily divide t
by s to get (x + y), from which then we have
s == x - y
t == x + y
i.e. x = (s+t)/2 and y=(t-s)/2 */
t /= s;
int x = (s + t) / 2;
int y = (t - s) / 2;
/* Now x, y are the distinct elements, x from array a and y from array b */
/* Fill in the results */
c[0] = x;
c[3] = y;
/* If a[0] is non-shared, then a[1] must be the first shared element; otherwise a[0] */
c[1] = (a[0] == x ? a[1] : a[0]);
/* If a[2] is non-shared, then a[1] must be the last shared element; otherwise a[2] */
c[2] = (a[2] == x ? a[1] : a[2]);
Пример: a = {1, 3, 5}, b = {3, 5, 2}
s = (1-3)+(3-5)+(5-2) = -2-2+3 = -1
t = (1-3)*(1+3)+(3-5)*(3+5)+(5-2)*(5+2) = -8-16+21 = -3
t / s = 3
x = (-1 + 3) / 2 = 1
y = (3 - (-1)) / 2 = 2
c[0] = 1
c[3] = 2
c[1] = 3
c[2] = 5
поэтому c получает значение {1,3,5,2}, как требуется!
Ради интереса, вот версия для компакт-диска:
/* Declarations */
int a[3], b[3], c[4];
int s = 0, t = 0, k, i;
/* Actual algorithm */
for (i = 0; i < 3; i++) { s += (k = a[i]-b[i]); t += k * (a[i]+b[i]); }
t /= s;
c[0] = (s + t) >> 1;
c[3] = (t - s) >> 1;
c[1] = (a[0] == x ? a[1] : a[0]);
c[2] = (a[2] == x ? a[1] : a[2]);
Обратите внимание, что достаточно круто, если задача обобщена, так что n-1 элементы являются общими, и в обоих массивах есть один уникальный элемент, это алгоритм O (n), тогда как в общем случае устанавливаются алгоритмы пересечения и / или объединения O (n log n):)