Java 查找数字数组中两个最近元素之间的距离

Java 查找数字数组中两个最近元素之间的距离,java,algorithm,Java,Algorithm,所以我在自学我买的这本书中的算法,我有一个伪代码,用来计算数字数组中两个最接近的元素之间的距离 MinDistance(a[0...n-1]) Input: Array A of numbers Output: Minimum Distance between two of its elements dMin <- maximum integer for i=0 to n-1 do for j=0 to n-1 do if i!=j and | A[i] - A[j]

所以我在自学我买的这本书中的算法,我有一个伪代码,用来计算数字数组中两个最接近的元素之间的距离

MinDistance(a[0...n-1])
Input: Array A of numbers
Output: Minimum Distance between two of its elements
dMin <- maximum integer

for i=0 to n-1 do
   for j=0 to n-1 do
      if i!=j and | A[i] - A[j] | < dMin
        dMin = | A[i]-A[j] |
return dMin
然而,我想对这个算法解决方案进行改进。更改已经存在的内容,或者一起重写。有人能帮忙吗? 我用Java编写函数和类来测试伪代码?对吗?再一次,从效率的角度来看,我怎样才能使它变得更好

//Scanner library allowing the user to input data
import java.lang.Math.*;

public class ArrayTester{
    //algorithm for finding the distance between the two closest elements in an array of numbers
    public int MinDistance(int [] ar){
    int [] a = ar;
    int aSize = a.length;
    int dMin = 0;//MaxInt
    for(int i=0; i< aSize; i++)
    {
        for(int j=i+1; j< aSize;j++)
        {   
            dMin = Math.min(dMin, Math.abs( a[i]-a[j] );
        }
    }
    return dMin;
}

    //MAIN
    public static void main(String[] args){

        ArrayTester at = new ArrayTester();
        int [] someArray = {9,1,2,3,16};
        System.out.println("NOT-OPTIMIZED METHOD");
        System.out.println("Array length = "+ someArray.length);
        System.out.println("The distance between the two closest elements: " + at.MinDistance(someArray));

    } //end MAIN

} //END CLASS
因此,我更新了函数以最小化调用Math.abs两次。我还能做些什么来改进它。如果我用sort重写它,它会改变我的for循环吗,还是会一样,只是理论上运行得更快

public int MinDistance(int [] ar){
        int [] a = ar;
        int aSize = a.length;
        int dMin = 0;//MaxInt
        for(int i=0; i< aSize; i++)
        {
            for(int j=i+1; j< aSize;j++)
            {   
                dMin = Math.min(dMin, Math.abs( a[i]-a[j] );
            }
        }
        return dMin;
    }

一个明显的效率改进是:首先对整数排序,然后可以查看相邻的整数。任何一个数字,无论是向上还是向下,都会离它的邻居最近

这将复杂性从On2更改为logn。诚然,对于n的小值,它不会产生显著的差异,但就理论复杂性而言,它很重要

您可能需要进行一个微观优化:使用局部变量存储Math.abs的结果,如果结果小于最小值,则无需重新计算。或者,您可能希望使用dMin=Math.mindMin,Math.absa[i]-a[j]

请注意,您需要注意边界条件-如果您允许负数,减法可能会溢出。

这里有一个问题:

如果对数组进行排序,找到最小距离需要多长时间


您应该可以从这里完成其余的工作。

这是^2上的一个简单解决方案

更好的方法:

对数组进行排序,然后再次检查并检查排序项之间的距离。 这将起作用,因为它们是按升序排列的,因此具有最近值的数字是相邻的


该解决方案将是唯一的。首先,在使其快速之前,请使其正确。为什么用数组的长度初始化dmin?如果数组是[1,1000],则算法的结果将是2,而不是999

那么,为什么要让j从0变为数组的长度呢?将每对元素进行两次比较。您应该使j从i+1变为数组的长度,这也将避免i!=j比较

最后,通过避免调用Math.abs两次,您可以获得几纳秒


然后,您可以通过首先对数组进行排序来完全更改算法,如其他答案中所述

理论上,你可以通过

通过编辑shell基数排序进行排序,感谢j_random_hacker指出了这一点 一次通过查找数字之间的差异
首先对数组进行排序可以避免使用另一个FOR循环

    public static int distclosest(int numbers[]) {
       Arrays.sort(numbers);
       int aSize = numbers.length;
       int dMin = numbers[aSize-1];

       for(int i=0; i<aSize-1; i++) {
                dMin = Math.min(dMin, numbers[i+1]-numbers[i]);
       }
       return dMin;
    }

np:在执行算法之前,必须对数组进行排序

static int minDist(int arr[]) {
    int firstPointer, nextPointer;
    int minDistance = arr[1] - arr[0];
    int tempDistance;

    for (firstPointer = 0; firstPointer < arr.length; firstPointer++) {
        for (nextPointer = firstPointer + 1; nextPointer < arr.length; nextPointer++) {
            if (arr[nextPointer] == arr[firstPointer]) {
                return 0;
            } else {
                tempDistance = (arr[nextPointer] - arr[firstPointer]);
                if (minDistance > tempDistance) {
                    minDistance = tempDistance;
                }
            }

        }
    }
    return minDistance;
}

public static void main(String[] args) {
    int[] testArray = {1000, 1007, 3, 9, 21};
    Arrays.sort(testArray);
    int result = minDist(testArray);
    System.out.println(result); 
}

由于他对整数进行排序,他可以进一步使用基数排序算法。在对数组进行排序时,如何找到数组中最近元素之间的距离?如果我们在排序,我们所能找到的就是哪两个元素彼此最接近。@Barry:那么,项目索引i的最近邻要么在索引i+1,要么在索引i-1,所以你可以很容易地找到最接近的距离。如果你明白我的意思的话,只需在数组上迭代以找到最小的最近距离。使用库排序对其进行排序?库排序可能实现得很好Shell排序未启用。根据维基百科,最佳界限根据所选的间隔序列而变化,但总是比Onlog n差。也许你在考虑桶排序?@j_random_hacker,+1表示感谢。修正了我的答案。user628796可以使用基数排序,因为问题空间是所有数字。您可以将dMin初始化为0,并使用//MaxInt对其进行注释。您可以使用integer.MAX_值获得java中的最大整数。
static int minDist(int arr[]) {
    int firstPointer, nextPointer;
    int minDistance = arr[1] - arr[0];
    int tempDistance;

    for (firstPointer = 0; firstPointer < arr.length; firstPointer++) {
        for (nextPointer = firstPointer + 1; nextPointer < arr.length; nextPointer++) {
            if (arr[nextPointer] == arr[firstPointer]) {
                return 0;
            } else {
                tempDistance = (arr[nextPointer] - arr[firstPointer]);
                if (minDistance > tempDistance) {
                    minDistance = tempDistance;
                }
            }

        }
    }
    return minDistance;
}

public static void main(String[] args) {
    int[] testArray = {1000, 1007, 3, 9, 21};
    Arrays.sort(testArray);
    int result = minDist(testArray);
    System.out.println(result); 
}