给定一个非常大的整数数组,我需要找到a4
的最大值,这样:
a4 = a1 + a2 + a3
其中ai是数组中的所有值。
我该怎么做?
注意:使用4 for循环不是理想的解决方案。
答案 0 :(得分:13)
有一个简单的(预期的)O(n ^ 2)解决方案:
如果你想避免多次使用一个元素,你需要在哈希表中存储一些额外的信息,这样你就可以过滤掉快速与a1或a4一致的对。
如果数组中的整数是有界的(max - min< = C),那么知道使用离散傅立叶变换(使用FFT可解)可以实现O(n + C log C)可能是有用的。
答案 1 :(得分:2)
首先,您应该升序对数组进行排序。然后从数组的最后一个(最大)成员开始。 例如,对于[1,2,3,777,999,111,665],您已经sortArray = {1,2,3,111,665,777,999} 然后选择999作为a4并尝试与其他成员一起创建它。因此,您应该选择a3并尝试创建(999 - 777)= 222作为a1 + a2,因为您的数组已排序,您只需要考虑子阵列{1,2,3,111}。如果没有满足此条件的对,请尝试下一个最大成员(777)并重试以上场景以找到解决方案
答案 2 :(得分:0)
根据@Niklas的回答,我用Java编写了以下程序。
public static int sumOfThree(int [] arr) {
int arrlen = arr.length;
int arrijv [][] = new int [arrlen * (arrlen - 1) / 2][3];
int arrijvlen = 0;
quickSortInDescendingOrder(arr, 0, arrlen - 1); // sorts array into descending order
System.out.println(Arrays.toString(arr));
// populates array with sum of all pair values
for (int i = 0; i < arrlen - 1; i++) {
for (int j = i + 1; j < arrlen; j++) {
// if ((arr[i] + arr[j]) < arr[0]) { // can be added if no negative values
arrijv[arrijvlen][0] = i;
arrijv[arrijvlen][1] = j;
arrijv[arrijvlen][2] = arr[i] + arr[j];
arrijvlen++;
// }
}
}
System.out.print('[');
for (int i = 0; i < arrijvlen; i++) {
System.out.print(arrijv[i][2] + " ");
}
System.out.print("]\n");
// checks for a match of difference of other pair in the populated array
for (int i = 0; i < arrlen - 1; i++) {
for (int j = i + 1; j < arrlen; j++) {
int couldBeA4 = arr[i];
if(isAvailable(arrijv, arrijvlen, couldBeA4 - arr[j], i, j)){
System.out.println(" i3-" + j + " i4-" + i);
return couldBeA4;
}
}
}
return -1;
}
private static boolean isAvailable(int[][] arrijv, int len, int diff, int i, int j) {
boolean output = false;
// returns true if the difference is matched with other combination of i,j
for (int k = 0; k < len; k++) {
if (arrijv[k][2] == diff) {
int pi = arrijv[k][0];
int pj = arrijv[k][1];
if (pi != i && pi != j && pj != i && pj != j) {
System.out.print("i1-" + pj + " i2-" + pi);
output = true;
break;
}
}
}
return output;
}
private static void quickSortInDescendingOrder(int[] array, int low, int high) { // solely used for sorting input array into descending array
if (low < high) {
int partition = getPartitionIndex(array, low, high);
quickSortInDescendingOrder(array, low, partition);
quickSortInDescendingOrder(array, partition + 1, high);
}
}
private static int getPartitionIndex(int[] arr, int lo, int hi) {
int pivot = arr[(lo + hi) / 2];
while (true) {
while (arr[lo] > pivot) {
lo++;
}
while (arr[hi] < pivot) {
hi--;
}
if (arr[lo] == arr[hi]) { // can be removed if no duplicate values
return lo;
} else if (lo < hi) {
int temp = arr[lo];
arr[lo] = arr[hi];
arr[hi] = temp;
} else {
return hi;
}
}
}
请确认其有效并建议进一步改进。