2012-11-04 10 views
6

Come si può trovare una mediana di 2 array ordinati A e B che sono rispettivamente di lunghezza m en. Ho cercato, ma la maggior parte degli algoritmi presuppone che entrambi gli array abbiano le stesse dimensioni. Voglio sapere come possiamo trovare la mediana se m! = N consideri l'esempio, A = {1, 3, 5, 7, 11, 15} dove m = 6, B = {2, 4, 8, 12 , 14} dove n = 5 e la mediana è 7Mediana di 2 array ordinati di lunghezze diverse

Qualsiasi aiuto è apprezzato. Mi sto preparando per le interviste e sto lottando con questo algo in questo momento.

+0

senza spazio in più .... so che il metodo per creare un terzo uso serie fusione tecnica come in unire sort e quindi trovare la mediana. questo è un approccio ingenuo e richiede uno spazio extra di O (m + n), stavo cercando un algoritmo che non usasse un array extra. – ravi

+0

Questa domanda ha avuto risposta in geeksforgeeks. Dai un'occhiata a questo ... http://www.geeksforgeeks.org/archives/24514 – premprakash

+0

È interessante il modo in cui hanno usato la ricerca binaria per ottenere O (LogM + LogN). La mia prima pugnalata sarebbe stata l'approccio lineare di O (M + N). – goat

risposta

2

Una ricerca lineare per l'elemento mediano è ordinata O (m + n) con spazio costante. Questo non è ottimale, ma è realistico da produrre in un'intervista.

numElements = arr1.length + arr2.length 
elementsToInspect = floor(numElements/2) 
i1 = 0 
i2 = 0 

if elementsToInspect == 0 
    return arr1[i1] 

while (1) { 
    if (arr1[i1] < arr2[i2]) { 
     i1++ 
     elementsToInspect-- 
     if elementsToInspect == 0 
      return arr1[i1] 
    } else { 
     i2++ 
     elementsToInspect-- 
     if elementsToInspect == 0 
      return arr2[i2] 
    } 
} 
7

Ecco il codice Java per trovare la mediana di due array ordinati di lunghezza diversa

package FindMedianBetween2SortedArraysOfUnequalLength; 

import java.util.Arrays; 
import java.util.Scanner; 

public class UsingKthSmallestElementLogic { 

public static void main(String[] args) { 
    Scanner in = new Scanner(System.in); 
    try{ 
     System.out.println("Enter the number of elements in the first SORTED array"); 
     int n = in.nextInt(); 
     int[] array1 = new int[n]; 
     System.out.println("Enter the elements of the first SORTED array"); 
     for(int i=0;i<n;i++) 
      array1[i]=in.nextInt(); 
     System.out.println("Enter the number of elements in the second SORTED array"); 
     int m = in.nextInt(); 
     int[] array2 = new int[m]; 
     System.out.println("Enter the elements of the second SORTED array"); 
     for(int i=0;i<m;i++) 
      array2[i]=in.nextInt(); 
     System.out.println("Median of the two SORTED arrays is: "+findMedian(array1,array2,array1.length,array2.length)); 
    } 
    finally{ 
     in.close(); 
    } 
} 
private static int findMedian(int[] a, int[] b, 
     int aLength, int bLength) { 

    int left = (aLength+bLength+1)>>1; 
    int right = (aLength+bLength+2)>>1; 
    return ((findKthSmallestElement(a,b,a.length,b.length,left)+findKthSmallestElement(a,b,a.length,b.length,right))/2); 
} 
private static int findKthSmallestElement(int[] a, int[] b, 
     int aLength, int bLength, int k) {     // All the 5 parameters passed are VERY VERY IMP 

    /* to maintain uniformity, we will assume that size_a is smaller than size_b 
    else we will swap array in call :) */ 
    if(aLength>bLength) 
     return findKthSmallestElement(b, a, bLength, aLength, k); 

    /* We have TWO BASE CASES 
    * Now case when size of smaller array is 0 i.e there is no elemt in one array*/ 
    //BASE CASE 1. If the smallest array length is 0 
    if(aLength == 0 && bLength > 0) 
      return b[k-1]; // due to zero based index 

    /* case where k==1 that means we have hit limit */ 
    //BASE CASE 2. If k==1 
    if(k==1) 
      return Math.min(a[0], b[0]); 

    /* Now the divide and conquer part */ 
    int i = Math.min(aLength, k/2) ; // k should be less than the size of array 
    int j = Math.min(bLength, k/2) ; // k should be less than the size of array 

    if(a[i-1] > b[j-1]) 
      // Now we need to find only K-j th element 
      return findKthSmallestElement(a, Arrays.copyOfRange(b, j, b.length), a.length, b.length -j, k-j); 
    else 
      return findKthSmallestElement(Arrays.copyOfRange(a, i, a.length), b, a.length-i, b.length, k-i); 
} 
} 
/* 
Analysis: 
    Time Complexity = O(log(n+m)) 
    Space Complexity = O(1)*/ 
+0

Ottima soluzione! È sufficiente considerare quando la lunghezza è pari o dispari. –

+0

L'algoritmo è in grado di gestire automaticamente sia le soluzioni pari che quelle dispari. Provalo da solo –

+0

Questo ha effettivamente la complessità O (log (min {n, m}))? Grazie. –

0
A simple O(log(m + n)) solution: watch video https://www.youtube.com/watch?v=LPFhl65R7ww 

class Solution { 
     public double findMedianSortedArrays(int[] arr1, int[] arr2) { 
        if(arr1 == null && arr2 == null) { 
       return -1; 
      } 
      if(arr1.length == 0 && arr2.length == 0) { 
       return -1; 
      } 

      int x = arr1.length; 
      int y = arr2.length; 

      if(x > y) { 
       return findMedianSortedArrays(arr2, arr1); 
      } 
      int low = 0; 
      int high = x; 
      while (low <= high) { 
       int partitionX = (low + high)/2; 
       int partitionY = (x + y + 1)/2 - partitionX; 

       int maxX = partitionX == 0 ? Integer.MIN_VALUE : arr1[partitionX - 1]; 
       int minX = partitionX == x ? Integer.MAX_VALUE : arr1[partitionX]; 

       int maxY = partitionY == 0 ? Integer.MIN_VALUE : arr2[partitionY - 1]; 
       int minY = partitionY == y ? Integer.MAX_VALUE : arr2[partitionY]; 

       if(maxX <= minY && maxY <= minX) { 
        if((x + y)%2 == 0) { 
         return (Math.max(maxX, maxY) + Math.min(minX, minY))/2.0; 
        } else { 
         return Math.max(maxX, maxY); 
        } 
       } else if(maxX > minY) { 
        high = partitionX - 1; 
       } else { 
        low = partitionX + 1; 
       } 
      } 
      return -1; 
     } 
    } 
Problemi correlati