我最近在接受采访时得到了这个问题:
给定一个数组,找到两个具有最大总和的数字,该数字也是数组中的一个元素。
输入:6 10 12 34 41 16 输出:16
[更新]我的代码如下:
public class Solution {
public static int findMaximumNumbers(int a[])
{
Set<Integer> set=new HashSet<>();
for(int n:a) set.add(n);
Arrays.sort(a);
int max=Integer.MIN_VALUE;
for(int i=a.length-1;i>0;i--)
{
for(int j=i;j>=0;j--)
{
int sum = a[i] + a[j];
if(set.contains(sum) && max<sum)
max=sum;
}
}
return max;
}
public static void main(String[] args) {
System.out.println( findMaximumNumbers(new int[]{ 6, 10, 12, 34, 40, 16, 41, 47, 74 }));
System.out.println( findMaximumNumbers(new int[]{ 2, 25, 35, 40, 42, 60 }));
}
}
该算法需要O(n ^ 2)时间复杂度。有人有更好的算法吗?
答案 0 :(得分:0)
这是我能想到的最快的。由于列表已排序,因此您向后工作,尝试查找是否有任何对加起来是数组中的最大剩余(i
循环)。它将尽可能快地短路,并给出正确的答案。在j
循环中,当您达到的值小于目标的一半时,倒计时停止(不使用迭代无法累加到目标的剩余值)。但我希望有人可以做得更好。 OP代码将进行n*(n-1)/2
次迭代,但即使没有解决方案,这个迭代也总会做得更少。
public static int findMaximumNumbers(int a[])
{
Set<Integer> set=new HashSet<>();
for(int n:a) set.add(n);
Arrays.sort(a);
if (a[0] == 0)
return a[a.length-1];
for(int i=a.length-1;i>0;i--)
{
int j = i-1;
int m = a[i] / 2;
while (j >= 0 && a[j] > m) {
if (set.contains(a[i]-a[j]))
return a[i];
j--;
}
}
return -1;
}
答案 1 :(得分:0)
如果您的数字是1到M范围内的整数,那么您可以通过以下方式在O(Mlog(M))中执行此操作:
示例Python代码:
import scipy.signal
import time
def hist(X):
"""Prepare a histogram of X"""
h = [0]*(max(X)+1)
for x in X:
h[x] += 1
return h
A = [6, 10, 12, 34, 41, 16]
H = hist(A)
R = scipy.signal.fftconvolve(H,H)
for x in sorted(A,reverse=True):
if R[x] > 0.5:
print x
break
else:
print 'No solutions'
关键是直方图的卷积是所有可能元素总和的直方图。
当然,如果您有100个数字,其值在1到10 ** 100之间,那么这将比您的O(n ^ 2)算法效率低,因此这仅在值有限时才有用。 / p>
答案 2 :(得分:-1)
如果您首先对数组进行排序,则可以按升序逐对检查,添加两个连续数字并检查它是否包含在数组中。
int myArray[];
Arrays.sort(myArray);
int a = -1, b, highest = Integer.MIN_VALUE;
for(int i = 0; i < myArray.length - 1; i++)
{
int sum = myArray[i] + myArray[i + 1];
int startCheck = i + 1;
while(myArray[startCheck] < sum && startCheck < myArray.length)
startCheck++;
if(myArray[startCheck] == sum && sum > highest)
{
a = i;
b = i + 1;
highest = sum;
}
}
// Found 2 elements whose sum is on the array
if(a != -1)
{
}