我有一个具有有限数量值的整数数组。我的工作是找出数组中任意两个元素之间的最小差异。
考虑数组包含
4, 9, 1, 32, 13
这里的差异是 4 和 1 之间的最小值,所以答案是 3。
解决这个问题的算法应该是什么。另外,我不知道为什么,但我觉得使用树,这个问题可以相对容易地解决。可以这样做吗?
我有一个具有有限数量值的整数数组。我的工作是找出数组中任意两个元素之间的最小差异。
考虑数组包含
4, 9, 1, 32, 13
这里的差异是 4 和 1 之间的最小值,所以答案是 3。
解决这个问题的算法应该是什么。另外,我不知道为什么,但我觉得使用树,这个问题可以相对容易地解决。可以这样做吗?
最小差异将是排序顺序中连续对之间的差异之一。对数组进行排序,并通过相邻数字对寻找最小的差异:
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);
您可以利用您正在考虑整数来制作线性算法的事实:
虽然所有答案都是正确的,但我想展示负责n log n
运行时的底层算法。找到两点之间的最小距离或在一维平面中找到最近点的分而治之的方法。
通用算法:
这是我在 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}`);
我会将它们放在一个堆中,O(nlogn)
然后一个接一个地弹出并获得我弹出的每个元素之间的最小差异。最后我会有最小的差异。但是,可能有更好的解决方案。
这实际上是对closest-pair
问题的重述one-dimension
。
https://en.wikipedia.org/wiki/Closest_pair_of_points_problem
http://www.cs.umd.edu/~samir/grant/cp.pdf
正如下面引用的维基百科文章所指出的,这个问题的最佳决策树模型也能Ω(nlogn)
及时运行。
分享最简单的解决方案。
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.
}
给定的问题可以在 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");
}
}
在 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)