这是来自Codility的三角问题:
给出了由N个整数组成的零索引数组A. 如果0≤P<1,则三重态(P,Q,R)是三角形。 Q&lt; R&lt; N和:
A [P] + A [Q]&gt; A [R],
A [Q] + A [R]> A [P],
A [R] + A [P]> A [Q]。写一个函数:
int solution(vector<int> &A);
给定由N个整数组成的零索引数组A,返回1 如果此数组存在三角形三元组并返回0 除此以外。
例如,给定阵列A使得:
A [0] = 10,A [1] = 2,A [2] = 5,A [3] = 1,A [4] = 8,A [5] = 20 三联(0,2,4)是三角形,函数应返回1.给定阵列A使得:
A [0] = 10,A [1] = 50,A [2] = 5,A [3] = 1 函数应返回0.假设:
N是[0..100,000]范围内的整数;
数组A的每个元素都是该范围内的整数 [-2,147,483,648..2,147,483,647]。
这是我在C ++中的解决方案:
int solution(vector<int> &A) {
if(A.size()<3) return 0;
sort(A.begin(), A.end());
for(int i=0; i<A.size()-2; i++){
//if(A[i] = A[i+1] = A[i+2]) return 1;
if(A[i]+A[i+1]>A[i+2] && A[i+1]+A[i+2]>A[i] && A[i+2]+A[i]>A[i+1]){
return 1;
}
}
return 0;
}
我检查了那里的评论,所有解决方案与我的相似 然而,虽然其他人声称已经获得100%,但我只获得了93%的分数 我得到了所有的测试用例除了一个:
extreme_arith_overflow1
溢出测试,3 MAXINTs
我认为这个案例有这样的输入:
[2147483647,2147483647,2147483647]
所以我将它添加到自定义测试用例中,当答案明显为1时,答案结果为0
我也试过[1900000000,1900000000,1900000000],答案仍然是0.
但是,[1000000000,1000000000,1000000000]是正确答案为1.
任何人都可以告诉我为什么会出现这种结果? 非常感谢。
答案 0 :(得分:2)
Java 100%:
public int solution(int[] A){
Arrays.sort(A);
for(int i=0;i<A.length-2;i++){
if(
((long)A[i] + (long)A[i+1] > A[i+2]) &&
((long)A[i+1] + (long)A[i+2] > A[i]) &&
((long)A[i] + (long)A[i+2] > A[i+1])
)
return 1;
}
return 0;
}
答案 1 :(得分:2)
这是我用Python编写的干净解决方案。我有100%的Codility。 这种逻辑可以适应任何其他编程语言。
注意::如果数组是 sorted ,则只需检查两个连续元素的和是否大于下一个元素(A [i] + A [i + 1]> A [i + 2]),因为在这种情况下,其他两个条件(A [i + 1] + A [i + 2]> A [i],A [i] + A [ i + 2]> A [i + 1])始终为真。
希望对您有帮助。
def solution(A):
#edge case check
if len(A) < 3:
return 0
A.sort()
for i in range(len(A)-2):
if A[i]+A[i+1] > A[i+2]:
return 1
return 0
答案 2 :(得分:1)
这里有几个问题
三角形的边不能为0,因为它是一个长度。您必须添加该检查,否则您将失败。即不会得到100%。
由于您可以拥有所有INT_MAX或LONG_MAX的输入数组(请参阅Linux example),因此您需要将该总和存储为双倍或长整数。
您无需在此检查所有三个条件,即
A [P] + A [Q]&gt; A [R], A [Q] + A [R]> A [P], A [R] + A [P]> A [Q]。
如果您对数组进行了排序而不是
A [Q] + A [R]> A [P]&amp;&amp;和 A [R] + A [P]> A [Q]
总是正确的,因为0≤P<1。 Q&lt; R即R大于P和Q.
因此,您只应检查A[P] + A[Q] > A[R]
。
您已经检查了A.size()&lt; 3这样很好。 我在http://www.cplusplus.com/reference/climits/添加了一个C实现。 您可以将其与解决方案进行比较
答案 3 :(得分:1)
我的Java解决方案具有100/100,时间复杂度为O(N * log(N))
带有解释逻辑的注释
// you can also use imports, for example:
// import java.util.*;
// you can write to stdout for debugging purposes, e.g.
// System.out.println("this is a debug message");
import java.util.Arrays;
class Solution {
public int solution(int[] A) {
int N = A.length;
if (N < 3) return 0;
Arrays.sort(A);
for (int i = 0; i < N - 2; i++) {
/**
* Since the array is sorted A[i + 2] is always greater or equal to previous values
* So A[i + 2] + A[i] > A[i + 1] ALWAYS
* As well ass A[i + 2] + A[i + 1] > A[i] ALWAYS
* Therefore no need to check those. We only need to check if A[i] + A[i + 1] > A[i + 2]?
* Since in case of A[i] + A[i + 1] > MAXINT the code would strike an overflow (ie the result will be greater than allowed integer limit)
* We'll modify the formula to an equivalent A[i] > A[i + 2] - A[i + 1]
* And inspect it there
*/
if (A[i] >= 0 && A[i] > A[i + 2] - A[i + 1]) {
return 1;
}
}
return 0;
}
基本上,当您检查整数的X + Y
值(大于整数限制)时,代码将在溢出时失败。因此我们无需检查X + Y > Z
,而只需检查等效语句X > Z - Y
(不是简单的数学方法吗?)。另外,您也可以始终使用long
,但这在解决方案存储方面会更糟。
还要确保您跳过负值,因为三角形不能有负边值。
欢呼
答案 4 :(得分:0)
简单的变化:首先,您观察到负整数不能是三角形三元组的一部分。这意味着您可以将所有整数转换为无符号整数,并且不再有任何溢出。
答案 5 :(得分:0)
排序现在不起作用,这是一个由 Codility 修复的错误。现在,我正在使用这段代码获得 93%
您可以在下面看到结果:
<块引用>0 <= P < Q < R < N
public static int solution(int[] unfilteredArray) {
int[] array = filterLessThanOneElements(unfilteredArray);
for(int i = 0; i <= (array.length - 3) ; i++) {
long p = array[i];
for(int j = i+1; j <= (array.length - 2); j++) {
long q = array[j];
for(int k = j+1; k <= (array.length - 1); k++) {
long r = array[k];
if((p + q > r) && (q + r > p) && (r + p > q)) {
return 1;
}
}
}
}
return 0;
}
// The mose efficient way to remove duplicates
// TIME COMPLEXITY : O(N)
private static int[] filterLessThanOneElements(int[] unfilteredArray) {
int k = 0;
for(int i = 0; i < unfilteredArray.length; i++) {
if(unfilteredArray[i] > 0) {
unfilteredArray[k++] = unfilteredArray[i];
}
}
return Arrays.copyOfRange(unfilteredArray, 0, k);
}
答案 6 :(得分:0)
不过,这是 javascript 解决方案(TC:O(N*log(N)),以防万一你们想要:)。
function solution(A) {
if(A.length<3) return 0;
A.sort((a,b)=>b - a);
for(let i = 0,j = i+1;j < A.length-1;j++){
let p = A[j],q = A[j+1],r = A[i]
if(r - p > q) i++;
else if(r - p < q) return 1;
}
return 0;
}
答案 7 :(得分:0)
我的C#解决方案得分为100。
const track1Subject$ = new Subject();
const track1$ = track1Subject$.asObservable();
const track2Subject$ = new Subject();
const track2$ = track2Subject$.asObservable();
const Observable1$ = timer(1000, 2000).pipe(
map(() => 1),
tap(console.log),
tap(() => track1Subject$.next()),
take(5)
);
const Observable2$ = timer(1700, 1700).pipe(
map(() => 2),
tap(console.log),
tap(() => track2Subject$.next()),
take(5)
);
const Observable3$ = combineLatest([track1$, track2$]).pipe(
take(1),
map(() => "Hello World!"),
tap(console.log)
);
Observable1$.subscribe();
Observable2$.subscribe();
Observable3$.subscribe();
答案 8 :(得分:0)
我的Java解决方案100/100我们没有比较加法,而是比较了减法,因为我们可以有一个 Integer.MAX_VALUE ,我们将获取损坏的数据。>
public static int solution(int[] A) {
int isATriangle = 0;
Arrays.sort(A);
if (A.length >= 3) {
for (int i = 0; i < A.length - 2; i++) {
if (A[i] > A[i + 2] - A[i + 1]
&& A[i + 2] > A[i] - A[i + 1]
&& A[i + 2] > A[i + 1] - A[i])
isATriangle = 1;
}
}
return isATriangle;
}
答案 9 :(得分:0)
诀窍是在数组上找到一个小于数组上其他两个数之和的数字,因此对数组进行排序然后搜索该数字即可解决该问题。强制转换,以至于有时总和的值会超过允许的整数
public int solution(int[] A) {
int n = A.length;
if(n<3){
return 0;
}
Arrays.sort(A);
for(int i=2; i<n; i++){
if(A[i]<(long)A[i-1]+(long)A[i-2])
return 1;
}
return 0;
}
答案 10 :(得分:0)
Ruby 100%解决方案
def solution(a)
arr = a.select{|x| x >=0 }.sort
arr.each_with_index do |p, pi|
arr[(pi+1)..-1].each_with_index do |q, qi|
arr[(qi+pi+2)..-1].each do |r|
break if p+q <=r
break if p+r <=q
break if r+q <=p
return 1
end
end
end
0
end
答案 11 :(得分:0)
//My solution in C++ it avoid overflow
inline int Triangle(vector<int> &A) {
if(A.size() < 3) return 0;
sort(A.begin(), A.end());
for(int i = 0; i < (int)A.size() - 2; ++i){
int P = A[i], Q = A[i + 1], R =A[i + 2];
if(( R - P - Q < 0) && ( P - Q - R < 0) && (Q - R - P < 0))
return 1;
}
return 0;
}
答案 12 :(得分:0)
工作100%,并在不同情况下进行了测试。
我认为解决方案未涵盖所有可能性 与结合 P,Q,R
A [0] = 10,A [1] = 2,A [2] = 5,A [3] = 1,A [4] = 8,A [5] = 20
索引组合
0 + 1> 2,1 + 2> 0,2 + 0> 1
1 + 2> 3,2 + 3> 1,3 + 1> 2
....
这些是解决此问题所需的组合。
//Triangle
/**
* A[P] + A[Q] > A[R],
A[Q] + A[R] > A[P],
A[R] + A[P] > A[Q]
*/
public int triangleSolution(int[] A) {
int status = 0;
for(int i=0; i<A.length; i++) {
int[] B = removeTheElement(A, i);
for(int j=0; j<B.length; j++) {
int[] C = removeTheElement(B, j);
for(int k=0; k<C.length; k++) {
if((A[i] + B[j] > C[k]) &&
(B[j] + C[k] > A[i]) &&
(C[k] + A[i] > B[j])) {
return 1;
}
}
}
}
return status;
}
// Function to remove the element
public int[] removeTheElement(int[] arr, int index)
{
// Create another array of size one less
int[] anotherArray = new int[arr.length - 1];
// Copy the elements except the index
// from original array to the other array
for (int i = 0, k = 0; i < arr.length; i++) {
// if the index is
// the removal element index
if (i == index) {
continue;
}
// if the index is not
// the removal element index
anotherArray[k++] = arr[i];
}
//Java >8
//IntStream.range(0, arr.length).filter(i -> i != index).map(i -> arr[i]).toArray();
return anotherArray;
}
答案 13 :(得分:0)
我在这里使用了3个for循环(不对数组进行排序)来解决此问题。
public static int solution(int[] A) {
for (int p = 0; p < A.length; p++) {
for (int q = p + 1; q < A.length; q++) {
for (int r = q + 1; r < A.length; r++) {
if ((A[p] + A[q] > A[r]) && (A[q] + A[r] > A[p]) && (A[r] + A[p] > A[q])) {
System.out.println(A[p] + " " + A[q] + " " + A[r]);
return 1;
}
}
}
}
return 0;
}
答案 14 :(得分:0)
或者您可以更改if子句,如下所示
if(A[i]>A[i+2]-A[i+1] && A[i+1]>A[i]-A[i+2] && A[i+2]>A[i+1]-A[i])
使用减法而不是加法。
答案 15 :(得分:0)
我用Swift编写的解决这个问题的方法。
public func Triangle(_ A : inout [Int]) -> Int {
A.sort()
for i in 1..<A.count-1 {
if(A[i] + A[i-1] > A[i+1]) {
print("Triangle has edges: \(A[i-1]), \(A[i]), \(A[i+1])")
return 1
}
}
return 0
}
A = [10,2,5,1,8,20]
print("Triangle: ", Triangle(&A))
答案 16 :(得分:-1)
这是因为integer overflow。
试试这个:
int a1 = 1900000000;
int a2 = 1900000000;
int sum = a1+a2; // sum will be -494967296
编辑:使用long long int。
long long int sum01 = A[i] + A[i+1];
long long int sum12 = A[i+1] + A[i+2];
long lont int sum02 = A[i] + A[i+2];
if (sum01 > A[i+2] && sum12 > A[i] && sum02 > A[i+1])
return 1;