Java Codibility测试中的溢出数

Java Codibility测试中的溢出数,java,algorithm,Java,Algorithm,在Codibility测试中,我得到了100%的性能和87%的正确性,其中一个测试失败 overflow arithmetic overflow tests got -1 expected 2 考虑到我使用的是64位的long,我看不出是什么导致了这种情况。即使我可以让它达到100%性能100%正确性,我想知道是否有一种更好的方法可以做到这一点,而不是像Java那样冗长 编辑:找到了一种更好的方法来处理两个数组,而不是一个pair类 // you can also use imports, f

在Codibility测试中,我得到了100%的性能和87%的正确性,其中一个测试失败

overflow
arithmetic overflow tests
got -1 expected 2
考虑到我使用的是64位的long,我看不出是什么导致了这种情况。即使我可以让它达到100%性能100%正确性,我想知道是否有一种更好的方法可以做到这一点,而不是像Java那样冗长

编辑:找到了一种更好的方法来处理两个数组,而不是一个pair类

// you can also use imports, for example:
 import java.util.*;

// you can use System.out.println for debugging purposes, e.g.
// System.out.println("this is a debug message");

class Solution {
    public int solution(int[] A) {
        int j = 0;
        Pair[] arr = new Pair[A.length * 2];
        for (int i = 0; i < A.length; i++) {
            Pair s = new Pair(i - A[i], true);
            arr[j] = s;
            j++;
            Pair e = new Pair(i + A[i], false);
            arr[j] = e;
            j++;
        }
        Arrays.sort(arr, new Pair(0, true));

        long numIntersect = 0;
        long currentCount = 0;
        for (Pair p: arr) {
            if (p.start) {
                numIntersect += currentCount;
                if (numIntersect > 10000000) {
                    return -1;
                }
                currentCount++;
            } else {
                currentCount--;
            }
        }

        return (int) numIntersect;
    }

    static private class Pair implements Comparator<Pair> {
        private long x;
        private boolean start;
        public Pair(long x, boolean start) {
            this.x = x;
            this.start = start;
        }

        public int compare(Pair p1, Pair p2) {
            if (p1.x < p2.x) {
                return -1;
            } else if (p1.x > p2.x) {
                return 1;
            } else {
                if (p1.start && p2.start == false) {
                    return -1;
                } else if (p1.start == false && p2.start) {
                    return 1;
                } else {
                    return 0;
                }
            }
        }
    }
}
//您也可以使用导入,例如:
导入java.util.*;
//您可以使用System.out.println进行调试,例如。
//System.out.println(“这是一条调试消息”);
类解决方案{
公共int解决方案(int[]A){
int j=0;
配对[]arr=新配对[A.长度*2];
for(int i=0;i10000000){
返回-1;
}
currentCount++;
}否则{
当前计数--;
}
}
返回(int)numIntersect;
}
静态私有类对实现了Comparator{
私人长x;
私有布尔启动;
公共对(长x,布尔起始){
这个.x=x;
this.start=start;
}
公共整数比较(对p1,对p2){
if(p1.xp2.x){
返回1;
}否则{
if(p1.start&&p2.start==false){
返回-1;
}else if(p1.start==false&&p2.start){
返回1;
}否则{
返回0;
}
}
}
}
}
看这一行:

Pair s = new Pair(i + A[i], true);
这相当于
对s=新对((长)(i+A[i]),true)

由于
i
是整数,而
A[i]
也是整数,因此这可能会导致溢出,因为
A[i]
中的值可能会上升到
integer.MAX\u值
,并且在add操作完成后发生对
long
的转换

要修复:

Pair s = new Pair((long)i + (long)A[i], true);
注意:我已提交了我的定金并获得100%

我今天的解决方案。O(N)时间复杂度。简单的假设是,表中下一点的可用对数是该时刻的总开口圆(圆)和之前处理过的圆之间的差值。也许很简单:)

public int solution04(int[]A){
最终整数N=A.长度;
最终整数M=N+2;
int[]left=new int[M];//该点圆的“左”边的nb值
int[]sleft=new int[M];//左[]的前缀和
int-il,ir;//圆的“左”边和“右”边的索引
对于(int i=0;i10000000){
总p=-1;
}
返回总p;
}
int tl(int i,int[]A){
int tl=i-A[i];//圆的“开始”索引
if(tl<0){
tl=0;
}否则{
tl=i-A[i]+1;
}
返回tl;
}
int tr(int i,int[]A,int M){
int tr;//圆的“结束”索引
if(Integer.MAX_值-i=M-1){
tr=M-1;
}否则{
tr=i+A[i]+1;
}
返回tr;
}
我对此的看法,O(n):

public int解决方案(int[]A){
int[]起始点=新的int[A.length];
int[]端点=新的int[A.length];
int温度点;
int currOpenCircles=0;
长对=0;
//起点和终点之和-在每个索引处打开和关闭多少圈?
for(int i=0;i=2)
配对+=(起始点[i]*(起始点[i]-1))/2;
pairs+=currenopencircles*起始点[i];
currOpenCircles+=起始点[i];
currOpenCircles-=端点[i];
如果(对>10000000)
返回-1;
}
返回(int)对;
}

赫尔辛解决方案部分的说明:

if(startPoints[i] >= 2) pairs += (startPoints[i] * (startPoints[i] - 1)) / 2; 
基于数学组合公式:

Cn,m = n! / ((n-m)!.m!
对于成对,m=2,则:

Cn,2 = n! / ((n-2)!.2
等于:

Cn,2 = n.(n-1).(n-2)! / ((n-2)!.2
通过简化:

Cn,2 = n.(n-1) / 2

不是很好的性能,但是使用流

List<Long> list = IntStream.range(0, A.length).mapToObj(i -> Arrays.asList((long) i - A[i], (long) i + A[i]))
            .sorted((o1, o2) -> {
                int f = o1.get(0).compareTo(o2.get(0));
                return f == 0 ? o1.get(1).compareTo(o2.get(1)) : f;
            })
            .collect(ArrayList<Long>::new,
                    (acc, val) -> {
                        if (acc.isEmpty()) {
                            acc.add(0l);
                            acc.add(val.get(1));
                        } else {
                            Iterator it = acc.iterator();
                            it.next();
                            while (it.hasNext()) {
                                long el = (long) it.next();
                                if (val.get(0) <= el) {
                                    long count = acc.get(0);
                                    acc.set(0, ++count);
                                } else {
                                    it.remove();
                                }
                            }
                            acc.add(val.get(1));
                        }
                    },
                    ArrayList::addAll);
    return (int) (list.isEmpty() ? 0 : list.get(0) > 10000000 ? -1 : list.get(0));
List List=IntStream.range(0,A.length).mapToObj(i->Arrays.asList((long)i-A[i],(long)i+A[i]))
.已排序((o1,o2)->{
intf=o1.get(0).与(o2.get(0))相比;
返回f==0?o1.get(1).compareTo(o2.get(1)):f;
})
.collect(数组列表::新建,
(acc,val)->{
如果(根据isEmpty()){
附件添加(0升);
Cn,2 = n.(n-1) / 2
List<Long> list = IntStream.range(0, A.length).mapToObj(i -> Arrays.asList((long) i - A[i], (long) i + A[i]))
            .sorted((o1, o2) -> {
                int f = o1.get(0).compareTo(o2.get(0));
                return f == 0 ? o1.get(1).compareTo(o2.get(1)) : f;
            })
            .collect(ArrayList<Long>::new,
                    (acc, val) -> {
                        if (acc.isEmpty()) {
                            acc.add(0l);
                            acc.add(val.get(1));
                        } else {
                            Iterator it = acc.iterator();
                            it.next();
                            while (it.hasNext()) {
                                long el = (long) it.next();
                                if (val.get(0) <= el) {
                                    long count = acc.get(0);
                                    acc.set(0, ++count);
                                } else {
                                    it.remove();
                                }
                            }
                            acc.add(val.get(1));
                        }
                    },
                    ArrayList::addAll);
    return (int) (list.isEmpty() ? 0 : list.get(0) > 10000000 ? -1 : list.get(0));