Java学习手册:(数据结构与算法-数组)如何求解最小三元组的距离?

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/MaybeForever/article/details/102483177

问题描述:

已知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
 

猜你喜欢

转载自blog.csdn.net/MaybeForever/article/details/102483177