I was stuck in solving the following interview practice question:
I have to write a function:
int triangle(int[] A);
that given a zero-
In Java:
public int triangle2(int[] A) {
if (null == A)
return 0;
if (A.length < 3)
return 0;
Arrays.sort(A);
for (int i = 0; i < A.length - 2 && A[i] > 0; i++) {
if (A[i] + A[i + 1] > A[i + 2])
return 1;
}
return 0;
}
A 100/100 php solution: http://www.rationalplanet.com/php-related/maxproductofthree-demo-task-at-codility-com.html
function solution($A) {
$cnt = count($A);
sort($A, SORT_NUMERIC);
return max($A[0]*$A[1]*$A[$cnt-1], $A[$cnt-1]*$A[$cnt-2]*$A[$cnt-3]);
}
In ruby what about
def check_triangle (_array)
for p in 0 .. _array.length-1
for q in p .. _array.length-1
for r in q .. _array.length-1
return true if _array[p] + _array[q] > _array[r] && _array[p] + _array[r] > _array[q] && _array[r] + _array[q] > _array[p]
end
end
end
return false
end
Just port it in the language of your choice
Here's my solution in C#, which gets 90% correctness (the wrong answer is returned for test extreme_arith_overflow1 -overflow test, 3 MAXINTs-
) and 100% performance.
private struct Pair
{
public int Value;
public int OriginalIndex;
}
private static bool IsTriplet(Pair a, Pair b, Pair c)
{
if (a.OriginalIndex < b.OriginalIndex && b.OriginalIndex < c.OriginalIndex)
{
return ((long)(a.Value + b.Value) > c.Value
&& (long)(b.Value + c.Value) > a.Value
&& (long)(c.Value + a.Value) > b.Value);
}
else if (b.OriginalIndex < c.OriginalIndex && c.OriginalIndex < a.OriginalIndex)
{
return ((long)(b.Value + c.Value) > a.Value
&&(long)(c.Value + a.Value) > b.Value
&& (long)(a.Value + b.Value) > c.Value);
}
// c.OriginalIndex < a.OriginalIndex && a.OriginalIndex < b.OriginalIndex
return ((long)(c.Value + a.Value) > b.Value
&& (long)(a.Value + b.Value) > c.Value
&& (long)(b.Value + c.Value) > a.Value);
}
public static int Triplets(int[] A)
{
const int IS_TRIPLET = 1;
const int IS_NOT_TRIPLET = 0;
Pair[] copy = new Pair[A.Length];
// O (N)
for (var i = 0; i < copy.Length; i++)
{
copy[i].Value = A[i];
copy[i].OriginalIndex = i;
}
// O (N log N)
Array.Sort(copy, (a, b) => a.Value > b.Value ? 1 : (a.Value == b.Value) ? 0 : -1);
// O (N)
for (var i = 0; i < copy.Length - 2; i++)
{
if (IsTriplet(copy[i], copy[i + 1], copy[i + 2]))
{
return IS_TRIPLET;
}
}
return IS_NOT_TRIPLET;
}
Here is an implementation of the algorithm proposed by Vlad. The question now requires to avoid overflows, therefore the casts to long long
.
#include <algorithm>
#include <vector>
int solution(vector<int>& A) {
if (A.size() < 3u) return 0;
sort(A.begin(), A.end());
for (size_t i = 2; i < A.size(); i++) {
const long long sum = (long long) A[i - 2] + (long long) A[i - 1];
if (sum > A[i]) return 1;
}
return 0;
}
Python:
def solution(A):
A.sort()
for i in range(0,len(A)-2):
if A[i]+A[i+1]>A[i+2]:
return 1
return 0
Sorting: Loglinear complexity O(N log N)