Java學習手冊:(數據結構與算法-數組)如何求解最小三元組的距離?

問題描述:

已知3個升序整數數組a[l]、b[m]、c[n]。請在3個數組中各找一個元素,使得組成的三元組距離最小。

三元組距離的定義是:假設a[i]、b[j]和c[k]是一個三元組,那麼距離爲Distance=max(|a[i]-b[j]|,|a[i]-c[k]|,|b[j]-c[k]|),請設計一個求最小三元組距離的最優算法。

方法一:

暴力法。分別遍歷3個數組中的元素,分別求出它們的距離,然後尋找最小距離。時間複雜度:O(l*m*n)。

方法一代碼如下:

package com.haobi;

public class Test32 {
	public static void main(String[] args) {
		int a[] = {3,4,5,7};
		int b[] = {10,12,14,16,17};
		int c[] = {20,21,23,24,37,38};
		System.out.println(minDistance(a,b,c));
	}
	
	public static int minDistance(int[]a, int[]b, int[]c) {
		int aLen = a.length;
		int bLen = b.length;
		int cLen = c.length;
		int minDist = max(Math.abs(a[0]-b[0]),Math.abs(b[0]-c[0]),Math.abs(a[0]-c[0]));
		int dist = 0;
		for(int i=0;i<aLen;i++) {
			for(int j=0;j<bLen;j++) {
				for(int k=0;k<cLen;k++) {
					//求距離
					dist = max(Math.abs(a[i]-b[j]),Math.abs(b[j]-c[k]),Math.abs(a[i]-c[k]));
					//記錄最小距離
					if(dist < minDist) {
						minDist = dist;
					}
				}
			}
		}
		return minDist;
	}
	
	public static int max(int a, int b, int c) {
		int max = a<b? b:a;
		max = max<c? c:max;
		return max;
	}
}

程序輸出結果如下:

13

方法二:

最小距離法。假設當前遍歷到這3個數組中的元素分別爲ai、bi、ci,並且ai<bi<ci,此時它們的距離肯定爲Di = ci - ai,那麼可以分爲如下3種情況討論:

(1)如果接下來求ai、bi、ci+1 的距離,那麼由於ci+1 > ci,此時Di+1 = ci+1 - ai,因此Di+1 > Di,因此Di+1不可能爲最小距離。

(2)如果接下來求ai、bi+1、ci 的距離,分爲兩種清理:、如果bi+1 > ci,那麼此時它們的距離爲Di+1 = bi+1 - ai,顯然Di+1 > Di,因此Di+1不可能爲最小距離;、如果bi+1 <= ci,此時它們的距離仍然爲Di = ci - ai

(3)如果接下來求ai+1、bi、ci 的距離,如果ai+1 < |ci - ai| + ci,此時它們的距離Di+1 = ci - ai+1,顯然Di+1 < Di,因此Di+1可能是最小的距離。

綜上所述,從3個數組的第一個元素開始,先求出它們的距離minDist,接着找出這3個數中最小數對應的數組,只對這個數組的下標往後移一個位置,接着求3個數組中當前元素的距離,若比minDist小,則把當前距離賦值給minDist,以此類推,直至遍歷完其中一個數組。時間複雜度:O(l+m+n)。

方法二代碼如下:

package com.haobi;

public class Test33 {
	public static void main(String[] args) {
		int a[] = {3,4,5,7};
		int b[] = {10,12,14,16,17};
		int c[] = {20,21,23,24,37,38};
		System.out.println(minDistance(a,b,c));
	}
	
	public static int minDistance(int[]a, int[]b, int[]c) {
		int aLen = a.length;
		int bLen = b.length;
		int cLen = c.length;
		int curDist = 0;
		int min = 0;//當前最小值
		int minDist = Integer.MAX_VALUE;
		int i = 0;//數組a的下標
		int j = 0;//數組b的下標
		int k = 0;//數組c的下標
		while(true) {
			//求距離
			curDist = max(Math.abs(a[i]-b[j]),Math.abs(b[j]-c[k]),Math.abs(a[i]-c[k]));
			if(curDist < minDist) {
				minDist = curDist;
			}
			//找出當前遍歷到3個數組中的最小值
			min = min(a[i],b[j],c[k]);
			if(min == a[i]) {
				if(++i >= aLen) {
					break;
				}
			}else if(min == b[j]) {
				if(++j >= bLen) {
					break;
				}
			}else if(min == c[k]) {
				if(++k >= cLen) {
					break;
				}
			}
		}
		return minDist;
	}
	
	public static int min(int a, int b, int c) {
		int min = a<b? a:b;
		min = min<c? min:c;
		return min;
	}
	
	public static int max(int a, int b, int c) {
		int max = a<b? b:a;
		max = max<c? c:max;
		return max;
	}
}

程序輸出結果如下:

13
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章