我是studying Codility chapter 2 : Counting elements。
我试着进行练习,我想我有一个很好的解决方案O(n)。这是一个有效的解决方案? 这是在课程中提出的最佳解决方案更好的解决方案吗?
问题:给定一个整数m(1 m 1 000 000)和两个非空的,零索引的n个整数的数组A和B,a0,a1,..., a-1和b0,b1,...,bn-1分别为(0 ai,bi m)。目标是检查是否存在可以对这些数组执行的交换操作,使得数组A中的元素总和等于交换后数组B中元素的总和。通过交换操作,我们的意思是从数组A和中选择一个元素 数组B中的一个元素并进行交换。
我使用这些值测试了我的解决方案: int a [] = {2,7,12,16}; int b [] = {4,8,9}; m = 16;
注意:我评论了返回以查看交换的值。
public int resultat(int[] A, int B[], int max) {
int sumA = Arrays.stream(A).sum();
int sumB = Arrays.stream(B).sum();
int[] countA = count(A, max);
int[] countB = count(B, max);
int diff = sumA - sumB;
int diffMin = 0;
if (diff % 2 != 0) {
return -1;
}
diffMin = diff / 2;
if (sumA > sumB) {
if (diff < countA.length && diffMin < countB.length && countA[diff] != 0 && countB[diffMin] != 0) {
System.out.println("A:" + diff + "- B:" + diffMin);
//return 1;
}
} else {
if (diffMin < countA.length && diff < countB.length && countB[diff] != 0 && countA[diffMin] != 0) {
System.out.println("A:" + diffMin + "- B:" + diff);
//return 1;
}
}
return -1;
}
public int[] count(int[] X, int max) {
int[] p = new int[max + 1];
Arrays.fill(p, 0);
for (int i = 0; i < X.length; i++) {
p[X[i]] += 1;
}
return p;
}
答案 0 :(得分:2)
由于O(n + m)
和count(A, max)
次调用,您的解决方案为count(B, max)
。 count()
是线性的。
这不是有效的解决方案。反例:A = [1, 2, 4]
,B = [3, 5, 1]
,m = 5
。答案是true
,因为我们可以将2
与3
交换。您的代码会在ArrayIndexOutOfBoundsException: -2
上引发countB[diff]
,因为diff
是-2
。即使您使用diff = Math.abs(sumA - sumB)
保护它,算法仍然不正确,它将返回false
。
您不需要执行Arrays.fill(p, 0)
,int
默认值为0
。
您可以写p[X[i]] += 1
代替p[X[i]]++
。
答案 1 :(得分:0)
这是(我希望)一个正确的解决方案。 请注意,在检查dif不是奇数以使性能更高之后仍然可以进行计数。 另请注意,listA和listB数组用作零位的值从不使用。这也是为了更好地理解。我们不需要出现值0但我们需要出现最大值。
public boolean solution(int[] A, int[] B, int max) {
int[] listA = new int[max+1];
int[] listB = new int[max+1];
int listAsum =0;
int listBsum=0;
for(int i = 0; i<A.length; i++){
listA[A[i]]++;
listAsum +=A[i];
listBsum +=B[i];
}
int diff = listAsum - listBsum;
if(diff%2 == 1) return false;
diff /=2;
for(int i=0; i<A.length; i++){
if((B[i] - diff) >= 0 && (B[i]-diff) <= max && listA[(B[i]-diff)] > 0) return true;
}
return false;
}
答案 2 :(得分:0)
public boolean solution(int[] A, int[] B, int max) {
int[] count = new int[max + 1];//count(A, max);
int sum_a = 0; //Arrays.stream(A).sum();
int sum_b = 0;//Arrays.stream(B).sum();
for (int i = 0; i < A.length; i++) {
count[A[i]]++;
sum_a += A[i];
sum_b += B[i];
}
int d = sum_b - sum_a;
if (d % 2 == 1) return false;
d /= 2;
for (int i = 0; i < A.length; i++) {
if ((B[i] - d) >= 0 && (B[i] - d) <= max && count[(B[i] - d)] > 0)
return true;
}
return false;
}
public int[] count(int[] X, int max) {
int[] p = new int[max + 1];
Arrays.fill(p, 0);
for (int i = 0; i < X.length; i++) {
p[X[i]]++;
}
return p;
}