找出数组中元素之间的最小差异

时间:2012-09-02 02:12:39

标签: algorithm

我有一个整数数组,其值有限。我的工作是找到数组中任何两个元素之间的最小差异。

考虑数组包含

4, 9, 1, 32, 13

这里的差异最小值介于4和1之间,所以答案是3。

解决此问题的算法应该是什么?另外,我不知道为什么但我觉得使用树木,这个问题可以解决相对容易。可以这样做吗?

8 个答案:

答案 0 :(得分:39)

最小差异将是排序顺序中连续对之间的差异之一。对数组进行排序,并查看相邻数字对,寻找最小的差异:

int[] a = new int[] {4, 9, 1, 32, 13};
Arrays.sort(a);
int minDiff = a[1]-a[0];
for (int i = 2 ; i != a.length ; i++) {
    minDiff = Math.min(minDiff, a[i]-a[i-1]);
}
System.out.println(minDiff);

This prints 3.

答案 1 :(得分:12)

您可以利用您正在考虑整数的事实 制作线性算法:

  1. 第一关: 计算最大值和最小值
  2. 第二关: 分配一个长度为布尔数组(max - min + 1),false初始化, 并将数组中每个值的(value - min)值更改为true
  3. 第三关: 计算布尔数组的真值项的索引之间的差异。

答案 2 :(得分:6)

虽然所有答案都是正确的,但我想展示负责n log n运行时的基础算法。 划分和征服找到两点之间的最小距离或在一维平面中找到最近点的方法。

一般算法:

enter image description here

  • 设m =中位数(S)。
  • 将S分为S1,S2为m。
  • δ1=最近对(S1)。
  • δ2=最近对(S2)。
  • δ12是切口的最小距离。
  • 返回δ= min(δ1,δ2,δ12)。

以下是我在Javascript中创建的示例:

// Points in 1-D
var points = [4, 9, 1, 32, 13];

var smallestDiff;

function mergeSort(arr) {
  if (arr.length == 1)
    return arr;

  if (arr.length > 1) {
    let breakpoint = Math.ceil((arr.length / 2));
    // Left list starts with 0, breakpoint-1
    let leftList = arr.slice(0, breakpoint);
    // Right list starts with breakpoint, length-1
    let rightList = arr.slice(breakpoint, arr.length);

    // Make a recursive call
    leftList = mergeSort(leftList);
    rightList = mergeSort(rightList);

    var a = merge(leftList, rightList);
    return a;
  }
}

function merge(leftList, rightList) {
  let result = [];
  while (leftList.length && rightList.length) {
    // Sorting the x coordinates
    if (leftList[0] <= rightList[0]) {
      result.push(leftList.shift());
    } else {
      result.push(rightList.shift());
    }
  }

  while (leftList.length)
    result.push(leftList.shift());

  while (rightList.length)
    result.push(rightList.shift());

  let diff;
  if (result.length > 1) {
    diff = result[1] - result[0];
  } else {
    diff = result[0];
  }

  if (smallestDiff) {
    if (diff < smallestDiff)
      smallestDiff = diff;
  } else {
    smallestDiff = diff;
  }
  return result;
}

mergeSort(points);

console.log(`Smallest difference: ${smallestDiff}`);

答案 3 :(得分:4)

我会将它们放在O(nlogn)的堆中然后一个一个地弹出,并获得我弹出的每个元素之间的最小差异。最后,我会有最小的差异。但是,可能有更好的解决方案。

答案 4 :(得分:4)

这实际上是对closest-pairone-dimension问题的重述。 https://en.wikipedia.org/wiki/Closest_pair_of_points_problem http://www.cs.umd.edu/~samir/grant/cp.pdf

正如下面引用的维基百科文章所指出的,此问题的最佳决策树模型也会在Ω(nlogn)时间内运行。

答案 5 :(得分:1)

给定的问题可以在O(n)时间内轻松解决。看下面我写的代码。

    import java.util.Scanner;
    public class Solution {
    public static void main(String [] args) {
        Scanner input = new Scanner(System.in);
        int i, minDistance = 999999;
        boolean flag = false;
        int capacity = input.nextInt();
        int arr[] = new int[capacity];
        for (i = 0; i < capacity; i++) {
            arr[i] = input.nextInt();
        }

        int firstElement = input.nextInt();
        int secondElement = input.nextInt();

        int prev = 0;

        for (i = 0; i < capacity; i++) {
            if (arr[i] == firstElement || arr[i] == secondElement) {
                prev = i;
                break;
            }
        }

        for (; i < capacity; i++) {
            if(arr[i] == firstElement || arr[i] == secondElement) {
                if(arr[i] != arr[prev] && minDistance > Math.abs(i - prev)) {
                    minDistance = Math.abs(i - prev);
                    flag = true;
                    prev = i;
                } else {
                    prev = i;
                }
            }
        }

        if(flag)
            System.out.println(minDistance);
        else
            System.out.println("-1");
    }
}

答案 6 :(得分:0)

共享最简单的解决方案。

function FindMin(arr) {

    //sort the array in increasing order

    arr.sort((a,b) => {
       return a-b;
    });

    let min = arr[1]-arr[0];

    let n = arr.length;

    for (var i=0;i<n;i++) {

      let m = arr[i+1] - arr[i];
      if(m < min){
        m = min;
      }
    }

    return m; // minimum difference.
  }

答案 7 :(得分:-1)

在Python 3中,可以使用模块 itertools 简化此问题,该模块为列表提供可用的组合。从该列表中,我们可以找到每个组合的总和,并找到这些值的最小值。

import itertools

arr = [4, 9, 1, 32, 13]

if len(arr) > 1:
    min_diff = abs(arr[0] - arr[1])
else:
    min_diff = 0

for n1, n2 in itertools.combinations(arr, 2): # Get the combinations of numbers
    diff = abs(n1-n2) # Find the absolute difference of each combination
    if min_diff > diff:
        min_diff = diff # Replace incase a least differnce found

print(min_diff)