Java 查找两个最大和的数字,这也是数组中的一个元素

Java 查找两个最大和的数字,这也是数组中的一个元素,java,arrays,algorithm,Java,Arrays,Algorithm,我最近在一次采访中得到了这个问题: 给定一个数组,找到两个最大和的数字,这也是数组中的一个元素 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 +

我最近在一次采访中得到了这个问题:

给定一个数组,找到两个最大和的数字,这也是数组中的一个元素

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)
{

}
输入:61012344116 产出: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 }));
    }
}
公共类解决方案{
公共静态int findMaximumNumbers(int a[])
{
Set=newhashset();
对于(int n:a)集合,添加(n);
数组。排序(a);
int max=整数的最小值;
对于(int i=a.length-1;i>0;i--)
{
对于(int j=i;j>=0;j--)
{
整数和=a[i]+a[j];

if(set.contains(sum)&&max这是我能想到的最快的一个。由于列表已排序,您可以反向工作,尝试查找是否有任何对相加到数组中剩余的最大值(
I
循环)在
j
循环中,当你达到的值小于目标值的一半时,倒计时就会停止(没有必要迭代不能达到目标值的剩余值)。但我希望有人能做得更好。操作代码可以做到
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;
}
public static int findMaximumNumbers(int a[])
{
Set=newhashset();
对于(int n:a)集合,添加(n);
数组。排序(a);
如果(a[0]==0)
返回一个[a.length-1];
对于(int i=a.length-1;i>0;i--)
{
int j=i-1;
int m=a[i]/2;
而(j>=0&&a[j]>m){
if(集合包含(a[i]-a[j]))
返回一个[i];
j--;
}
}
返回-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)
{

}
int-myArray[];
Arrays.sort(myArray);
int a=-1,b,最高值=Integer.MIN_值;
for(int i=0;i最高值)
{
a=i;
b=i+1;
最高=总和;
}
}
//找到2个元素,其总和在数组上
如果(a!=-1)
{
}

如果您的数字是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)效率低算法,因此这仅在值有限的情况下才有用。

    只有当您有已排序的输入时,上述代码才能正常工作。您的输入看起来不是按升序排序的。更新了代码。谢谢!
    j=i
    是否正确?假设列表中也有20个,您可以执行10+10=20吗?从复杂性的角度来看,您需要执行
    n*(n-1)/2
    添加(或
    n^2
    ,如果这两个元素不需要区分的话)。我不认为你能比O(n^2)做得更好。没有旁注:不要写
    int a[]
    ,写
    int[/code>(括号影响类型,因此应该写在类型旁边,而不是变量名旁边).FYI:如果您将方法更改为使用
    findMaximumNumbers(int…a)
    ,则无需创建数组
    findMaximumNumbers(6、10、12、34、41、16)
    当输入被更正时,此操作将失败。谢谢。(我仅假设为正数)。问题没有说。如果输入为0 1 2 3 10,则输出必须为3,但您的代码将生成输出10。我当时不理解这个问题。任何两个元素都是[0,10]。如果只是关于正数,它应该可以正常工作。但如果是负数,如-2 0,则应生成-2,而不是-1。