c – 如何知道一个三角形三元组存在于我们的数组?

我被困在解决以下面试实践问题:
我必须写一个函数:

int triangle(int[] A);

给定由N个整数组成的零索引的数组A,如果存在三元组(P,Q,R)使得0 < P < Q<例如, N.

A[P] + A[Q] > A[R],  
A[Q] + A[R] > A[P],  
A[R] + A[P] > A[Q].

如果此类三元组不存在,函数应返回0。假设0 < N < 100,000。假设数组的每个元素是范围[-1,000,000..1,000,000]中的整数。 例如,给定数组A

A[0]=10, A[1]=2, A[2]=5, A[3]=1, A[4]=8, A[5]=20

函数应返回1,因为三元组(0,2,4)满足所有必需的条件。

对于数组A这样

A[0]=10, A[1]=50, A[2]=5, A[3]=1

该函数应返回0。

如果我做一个三重循环,这将是非常非常慢(复杂性:O(n ^ 3))。我想可能用来存储一个额外的数组副本和排序,并使用二进制搜索特定的数字。但我不知道如何打破这个问题。
有任何想法吗?

首先,你可以排序你的序列。对于排序的序列,足以检查A [i] A [j] A [k] j < k,因为A [i] A [k] A [k] A [j]等,所以其他2个不等式自动为真。 (从现在起,i A [j 1],因为其他A [k]甚至更大(因此如果不等式适用于某些k,它也适用于k = j 1)。

接下来,足以检查A [j-1] A [j] A [j 1],因为其他A [i]甚至更小(因此如果不等式适用于一些i,它也适用于i = j-1)。

所以,你只有一个线性检查:你需要检查是否至少一个j A [j-1] A [j]> A [j 1]成立。

总共O(N log N){sort} O(N){check} = O(N log N)。

处理关于负数的评论:的确,这是我没有在原始解决方案中考虑。考虑负数不会改变解,因为没有负数可以是三角形的一部分。实际上,如果A [i],A [j]和A [k]形成三角形,则A [i] A [j] A [k],A [i] A [k] A [j],其暗示2 * A [i] A [j] A [k] A [k] A [j],因此2 * A [i] 0,所以A [i] 0和对称性A [j] 0,A [k] 0。

这意味着我们可以安全地从序列中删除负数和零,这在排序后在O(log n)中完成。

http://stackoverflow.com/questions/5391207/how-to-know-that-a-triangle-triple-exists-in-our-array

本站文章除注明转载外,均为本站原创或编译
转载请明显位置注明出处:c – 如何知道一个三角形三元组存在于我们的数组?