1. 程式人生 > 其它 >如何求最小三元組距離

如何求最小三元組距離

題目描述:

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

  三元組的距離定義是:假設a[i]、b[j]和c[k]是一個三元組,那麼距離為:Distance = max(|a[i]–b[j]|,|a[i]–c[k]|,|b[j]–c[k]|)請設計一個求最小三元組距離的最優演算法,並分析時間複雜度。

關鍵公式:max(|a[i]–b[j]|,|a[i]–c[k]|,|b[j]–c[k]|) = (abs(a[i]-b[j])+abs(a[i]-c[k])+abs(b[j]-c[k]))/2

思路:

方法一

  暴力法,三層迴圈,時間複雜度為O(l*m*n)

方法二:最小距離法

  假設當前遍歷到的這三個陣列中的元素分別為a[i],b[j],c[k],並且有a[i]<=b[j]<=c[k],則最小距離肯定是D = c[k]-a[i],那麼接下來有三種情況:

  1. 接下來求a[i],b[j],c[k+1]的最小距離,因為c[k+1]>=c[k],所以,此時的最小距離為c[k+1]-a[i],肯定大於D
  2. 接下來求a[i],b[j+1],c[k]的最小距離,如果b[j+1]<=c[k],則最小距離不變,如果b[j+1]>c[k],此時的最小距離為b[j+1]-a[i],同樣,肯定也是大於D
  3. 接下來求a[i],b[j+1],c[k]的最小距離,如果a[i+1] < c[k] + (c[k]-a[i]),則此時的最小距離顯然會小於D.

  所以,我們每次將最小的元素的index加1,才有可能將最小距離更優。所以,整體的思路是開始得出三個陣列第一個元素的最小距離,接下來移動最小三個元素中最小元素的下標,與之前得到的最小距離比較,看是否需要更新最小距離,直到遍歷完三個陣列,時間複雜度為O(l+m+n)

 1 public static int minDistance(int [] a,int [] b, int [] c){
 2     int curDis = 0 ;
 3     int min = 0 ;
 4     int minDis = Integer.MIN_VALUE ;
 5     int i = 0 ;
 6     int j = 0 ;
 7     int k = 0 ;
 8     
 9     while(i < a.length && j < b.length && k < c.length){
10         curDis = max(Math.abs(a[i]-b[j]),Math.abs(a[i]-c[k]),Math.abs(b[j]-c[k])) ;
11         if(curDis < minDis){
12             minDis = curDis ;
13         }
14         
15         min = min(a[i], b[j], c[k]) ;
16         if(min == a[i]){
17             i++ ;
18         }else if(min == b[j]){
19             j++ ;
20         }else{
21             k++ ;
22         }
23     }
24     return minDis ;
25 }
26 
27 private static int max(int a, int b, int c) {
28     int max = a > b ? a : b ;
29     max = max > c ? max : c ;
30     return max ;
31 }
32 
33 private static int min(int a, int b, int c) {
34     int min = a < b ? a : b ;
35     min = min < c ? min : c ;
36     return min ;
37 }