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

时间:2011-02-22 19:16:11

标签: 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] | < 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;
    }

8 个答案:

答案 0 :(得分:12)

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

这将复杂性从O(n 2 )改为O(n log n)。不可否认,n的小值显示它不会产生显着差异,但就理论复杂性而言,它很重要。

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

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

答案 1 :(得分:2)

这是O(n ^ 2)的天真解决方案。

更好的方式:

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

该解决方案将是O(nlogn)

答案 2 :(得分:2)

首先,在快速启动之前,请将其设为正确。为什么用dmin初始化数组的长度?如果数组为[1, 1000],则算法的结果将为2而不是999。

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

最后,你可以避免两次调用Math.abs()来获得几纳秒的时间。

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

答案 3 :(得分:1)

这是一个问题:

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

你应该可以从这里完成休息。

答案 4 :(得分:1)

理论上你可以通过

获得O(n)解决方案
  1. 使用 shell 基数排序排序(编辑,感谢j_random_hacker指出)
  2. 找到数字之间的差异

答案 5 :(得分:0)

首先对数组进行排序将使我们免于使用另一个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;
    }

答案 6 :(得分:0)

  static void MinNumber(int [] nums){

    Arrays.sort(nums);
    int min = nums[1] - nums[0]; 
    int indexOne = 0 , indexTwo = 1;

    for (int i = 1; i < nums.length -1; i++) {
        if (min > (nums[i+1] - nums[i])) {
            min = nums[i+1] - nums[i] ; 
            indexOne = i ; 
            indexTwo = i+1 ; 
        }
    }

    System.out.println("Minimum number between two values is: "+ min + " and the values is "+nums[indexOne]+" , "+nums[indexTwo] );

}

答案 7 :(得分:0)

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); 
}