[英]Finding the distance between the two closest elements in an array of numbers
所以我正在從我購買的這本書中自學算法,並且我有一個偽代碼用於查找數字數組中兩個最接近的元素之間的距離
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;
}
一個明顯的效率提升:先對整數進行排序,然后才能查看相鄰的整數。 任何數字都將最接近其鄰居,無論是向上還是向下。
這將復雜性從 O(n 2 ) 更改為 O(n log n)。 誠然,對於n
顯示的小值,它不會產生顯着差異,但就理論復雜性而言,這很重要。
您可能想要進行的一項微優化:使用局部變量來存儲Math.abs
的結果,如果結果小於最小值,則無需重新計算它。 或者,您可能想要使用dMin = Math.min(dMin, Math.abs(a[i] - a[j]))
。
請注意,您需要注意邊界條件 - 如果您允許負數,您的減法可能會溢出。
這是 O(n^2) 的簡單解。
更好的方法:
對數組進行排序,然后再次檢查它並檢查已排序項之間的距離。
這將起作用,因為它們按升序排列,因此具有最近值的數字是相鄰的。
該解決方案將是 O(nlogn)
首先,在使其快速之前,先使其正確。 為什么dmin
用數組的長度初始化? 如果數組是[1, 1000]
,則算法的結果將是 2 而不是 999。
那么,為什么要讓 j 從 0 到數組的長度呢? 您將每對元素比較兩次。 你應該讓 j 從 i + 1 到數組的長度(這也將避免 i != j 比較)。
最后,您可以通過避免調用 Math.abs() 兩次來獲得幾納秒的時間。
然后,您可以通過首先對數組進行排序來完全更改算法,如其他答案中所述。
這里有一個問題:
如果數組已排序,找到最小距離需要多長時間?
你應該可以從這里完成剩下的工作。
理論上,您可以通過以下方式獲得 O(n) 解決方案
首先對數組進行排序將使我們免於使用另一個 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;
}
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] );
}
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);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.