web-dev-qa-db-fra.com

Comment fusionner deux tableaux triés dans un tableau trié?

Cela m'a été demandé lors d'une interview et voici la solution que j'ai fournie:

public static int[] merge(int[] a, int[] b) {

    int[] answer = new int[a.length + b.length];
    int i = 0, j = 0, k = 0;
    while (i < a.length && j < b.length)
    {
        if (a[i] < b[j])
        {
            answer[k] = a[i];
            i++;
        }
        else
        {
            answer[k] = b[j];
            j++;
        }
        k++;
    }

    while (i < a.length)
    {
        answer[k] = a[i];
        i++;
        k++;
    }

    while (j < b.length)
    {
        answer[k] = b[j];
        j++;
        k++;
    }

    return answer;
}

Y at-il un moyen plus efficace de le faire? 

Edit: méthodes de longueur corrigées.

154
Behrooz Karjoo

Une amélioration mineure, mais après la boucle principale, vous pouvez utiliser System.arraycopy pour copier la queue de l'un des tableaux d'entrée lorsque vous arrivez à la fin de l'autre. Cela ne changera cependant pas les caractéristiques de performance de O(n) de votre solution.

33
Greg Hewgill
public static int[] merge(int[] a, int[] b) {

    int[] answer = new int[a.length + b.length];
    int i = 0, j = 0, k = 0;

    while (i < a.length && j < b.length)  
       answer[k++] = a[i] < b[j] ? a[i++] :  b[j++];

    while (i < a.length)  
        answer[k++] = a[i++];


    while (j < b.length)    
        answer[k++] = b[j++];

    return answer;
}

Est-ce un peu plus compact mais exactement le même!

102
Mike Saull

Je suis surpris que personne n'ait mentionné cette implémentation beaucoup plus cool, efficace et compacte:

public static int[] merge(int[] a, int[] b) {
    int[] answer = new int[a.length + b.length];
    int i = a.length - 1, j = b.length - 1, k = answer.length;

    while (k > 0)
        answer[--k] =
                (j < 0 || (i >= 0 && a[i] >= b[j])) ? a[i--] : b[j--];
    return answer;
}

Points d'intérêt

  1. Notez qu'il effectue le même nombre d'opérations ou un nombre inférieur à celui de tout autre algorithme O(n), mais dans une instruction littéralement unique dans une seule boucle while! 
  2. Si deux tableaux ont approximativement la même taille, la constante pour O(n) est identique. Cependant, si les tableaux sont vraiment déséquilibrés, les versions avec System.arraycopy gagneraient, car elles peuvent le faire en interne avec une seule instruction d'assemblage x86.
  3. Notez a[i] >= b[j] au lieu de a[i] > b[j]. Cela garantit la "stabilité" définie lorsque les éléments de a et b sont égaux, nous voulons les éléments de a avant b. 
54
Shital Shah

Toutes les améliorations qui pourraient être apportées seraient des micro-optimisations, l'algorithme global est correct.

16
ChrisH

Cette solution est également très similaire à d’autres publications, à la différence qu’elle utilise System.arrayCopy pour copier les éléments de tableau restants.

private static int[] sortedArrayMerge(int a[], int b[]) {
    int result[] = new int[a.length +b.length];
    int i =0; int j = 0;int k = 0;
    while(i<a.length && j <b.length) {
        if(a[i]<b[j]) {
            result[k++] = a[i];
            i++;
        } else {
            result[k++] = b[j];
            j++;
        }
    }
    System.arraycopy(a, i, result, k, (a.length -i));
    System.arraycopy(b, j, result, k, (b.length -j));
    return result;
}
10

Voici la fonction mise à jour. Il supprime les doublons, espérons que quelqu'un le trouvera utilisable:

public static long[] merge2SortedAndRemoveDublicates(long[] a, long[] b) {
    long[] answer = new long[a.length + b.length];
    int i = 0, j = 0, k = 0;
    long tmp;
    while (i < a.length && j < b.length) {
        tmp = a[i] < b[j] ? a[i++] : b[j++];
        for ( ; i < a.length && a[i] == tmp; i++);
        for ( ; j < b.length && b[j] == tmp; j++);
        answer[k++] = tmp;
    }
    while (i < a.length) {
        tmp = a[i++];
        for ( ; i < a.length && a[i] == tmp; i++);
        answer[k++] = tmp;
    }
    while (j < b.length) {
        tmp = b[j++];
        for ( ; j < b.length && b[j] == tmp; j++);
        answer[k++] = tmp;
    }
    return Arrays.copyOf(answer, k);
}
7
vitali_y

Cela peut être fait en 4 déclarations comme ci-dessous

 int a[] = {10, 20, 30};
 int b[]= {9, 14, 11};
 int res[]=new int[a.legth+b.length]; 
 System.arraycopy(a,0, res, 0, a.length); 
 System.arraycopy(b,0,res,a.length, b.length);
 Array.sort(res)

5
Sudhir

Les collections Apache supportent la méthode collate depuis la version 4; vous pouvez le faire en utilisant la méthode collate dans:

org.Apache.commons.collections4.CollectionUtils

Voici la citation de javadoc:

collate(Iterable<? extends O> a, Iterable<? extends O> b, Comparator<? super O> c)

Fusionne deux collections triées, a et b, en une seule, Liste triée telle que l'ordre des éléments selon Le comparateur c est retenu.

Ne réinventez pas la roue! Référence du document: http://commons.Apache.org/proper/commons-collections/apidocs/org/Apache/commons/collections4/CollectionUtils.html

4
Vlad

Je devais l'écrire en javascript, la voici:

function merge(a, b) {
    var result = [];
    var ai = 0;
    var bi = 0;
    while (true) {
        if ( ai < a.length && bi < b.length) {
            if (a[ai] < b[bi]) {
                result.Push(a[ai]);
                ai++;
            } else if (a[ai] > b[bi]) {
                result.Push(b[bi]);
                bi++;
            } else {
                result.Push(a[ai]);
                result.Push(b[bi]);
                ai++;
                bi++;
            }
        } else if (ai < a.length) {
            result.Push.apply(result, a.slice(ai, a.length));
            break;
        } else if (bi < b.length) {
            result.Push.apply(result, b.slice(bi, b.length));
            break;
        } else {
            break;
        }
    }
    return result;
}
3
ebdr

Fusion de GallopSearch: O (log (n) * log (i)) plutôt que O (n)

Je suis allé de l'avant et mis en œuvre la suggestion de Greybeard dans les commentaires. Principalement parce que j'avais besoin d'une version très efficace de ce code pour la mission.

  • Le code utilise un gallopSearch qui est O(log(i)), où i est la distance De l'index actuel, l'index pertinent existe.
  • Le code utilise une recherche binaire après que la recherche au galop a identifié la gamme appropriée. Puisque le galop limitait cette valeur à une plage plus petite , La recherche binaire résultante est également O (log (i)).
  • Le galop et la fusion sont effectués à l'envers. Cela ne semble pas être une mission critique, mais cela permet la fusion en place de tableaux. Si l'un de vos tableaux dispose de suffisamment d'espace pour stocker les valeurs de résultats, vous pouvez simplement l'utiliser comme tableau de fusion et le tableau de résultats. Vous devez spécifier la plage valide dans le tableau dans un tel cas.
  • Dans ce cas, il n’est pas nécessaire d’allouer de la mémoire (grandes économies d’opérations critiques). Il s'assure simplement que ce n'est pas le cas et ne peut pas écraser les valeurs non traitées (ce qui ne peut être fait que vers l'arrière). En fait, vous utilisez le même tableau pour les deux entrées et les résultats. Il ne subira aucun effet néfaste.
  • J'ai toujours utilisé Integer.compare () afin que cela puisse être utilisé à d'autres fins.
  • Il est possible que j'aie un peu gaffé et que je n'ai pas utilisé les informations que j'ai déjà prouvées. Tels que la recherche binaire dans une plage de deux valeurs, pour lesquelles une valeur a déjà été vérifiée. Il pourrait également exister un meilleur moyen d’énoncer la boucle principale; la valeur c inversée ne serait pas nécessaire si elles étaient combinées en deux opérations successives. Puisque vous savez que vous ferez l'un puis l'autre à chaque fois. Il y a de la place pour un peu de vernis.

Cela devrait être le moyen le plus efficace de le faire, avec une complexité temporelle de O (log (n) * log (i)) plutôt que O (n). Et dans le pire des cas, la complexité temporelle de O (n). Si vos tableaux sont agglomérés et ont de longues chaînes de valeurs ensemble, cela vous empêchera de le faire autrement, sinon ce sera tout simplement meilleur qu'eux.

Il a deux valeurs de lecture aux extrémités du tableau de fusion et la valeur d'écriture dans le tableau de résultats. Après avoir découvert que la valeur finale est inférieure, il effectue une recherche au galop dans ce tableau. 1, 2, 4, 8, 16, 32, etc. Quand il trouve la plage où la valeur de lecture de l'autre tableau est plus grande. Il effectue une recherche binaire dans cette plage (coupe la plage en deux, recherche la bonne moitié, répétition jusqu'à la valeur unique). Ensuite, le tableau copie ces valeurs dans la position d'écriture. Gardez à l'esprit que la copie est nécessairement déplacée de telle sorte qu'elle ne puisse pas écraser les mêmes valeurs du tableau de lecture (ce qui signifie que le tableau d'écriture et le tableau de lecture peuvent être identiques). Il effectue ensuite la même opération pour l'autre tableau, dont on sait maintenant qu'il est inférieur à la nouvelle valeur de lecture de l'autre tableau.

static public int gallopSearch(int current, int[] array, int v) {
    int d = 1;
    int seek = current - d;
    int prevIteration = seek;
    while (seek > 0) {
        if (Integer.compare(array[seek], v) <= 0) {
            break;
        }
        prevIteration = seek;
        d <<= 1;
        seek = current - d;
        if (seek < 0) {
            seek = 0;
        }
    }
    if (prevIteration != seek) {
        seek = binarySearch(array, seek, prevIteration, v);
        seek = seek >= 0 ? seek : ~seek;
    }
    return seek;
}

static public int binarySearch(int[] list, int fromIndex, int toIndex, int v) {
    int low = fromIndex;
    int high = toIndex - 1;
    while (low <= high) {
        int mid = (low + high) >>> 1;
        int midVal = list[mid];
        int cmp = Integer.compare(midVal, v);
        if (cmp < 0) {
            low = mid + 1;
        } else if (cmp > 0) {
            high = mid - 1;
        } else {
            return mid;// key found
        }
    }
    return -(low + 1);// key not found.
}

static public int[] sortedArrayMerge(int[] a, int[] b) {
    return sortedArrayMerge(null, a, a.length, b, b.length);
}

static public int[] sortedArrayMerge(int[] results, int[] a, int aRead, int b[], int bRead) {
    int write = aRead + bRead, length, gallopPos;
    if ((results == null) || (results.length < write)) {
        results = new int[write];
    }
    if (aRead > 0 && bRead > 0) {
        int c = Integer.compare(a[aRead - 1], b[bRead - 1]);
        while (aRead > 0 && bRead > 0) {
            switch (c) {
                default:
                    gallopPos = gallopSearch(aRead, a, b[bRead-1]);
                    length = (aRead - gallopPos);
                    write -= length;
                    aRead = gallopPos;
                    System.arraycopy(a, gallopPos--, results, write, length);
                    c = -1;
                    break;
                case -1:
                    gallopPos = gallopSearch(bRead, b, a[aRead-1]);
                    length = (bRead - gallopPos);
                    write -= length;
                    bRead = gallopPos;
                    System.arraycopy(b, gallopPos--, results, write, length);
                    c = 1;
                    break;
            }
        }
    }
    if (bRead > 0) {
        if (b != results) {
            System.arraycopy(b, 0, results, 0, bRead);
        }
    } else if (aRead > 0) {
        if (a != results) {
            System.arraycopy(a, 0, results, 0, aRead);
        }
    }
    return results;
}

Cela devrait être le moyen le plus efficace de le faire.


Certaines réponses avaient une capacité de suppression des doublons. Cela nécessitera un algorithme O(n) car vous devez réellement comparer chaque élément. Voici donc un document autonome à appliquer après coup. Vous ne pouvez pas galoper plusieurs entrées si vous devez toutes les regarder, mais vous pourriez galoper si vous en avez beaucoup.

static public int removeDuplicates(int[] list, int size) {
    int write = 1;
    for (int read = 1; read < size; read++) {
        if (list[read] == list[read - 1]) {
            continue;
        }
        list[write++] = list[read];
    }
    return write;
}

Mise à jour: réponse précédente, pas un code horrible mais nettement inférieur à ce qui précède.

Une autre hyper-optimisation inutile. Il appelle non seulement arraycopy pour les bits de fin, mais également pour le début. Traitement de tout non-recouvrement introductif dans O(log(n)) par un binarySearch dans les données. O(log(n) + n) correspond à O(n) et dans certains cas, l'effet sera assez prononcé, notamment lorsqu'il n'existe pas de chevauchement entre les matrices de fusion.

private static int binarySearch(int[] array, int low, int high, int v) {
    high = high - 1;
    while (low <= high) {
        int mid = (low + high) >>> 1;
        int midVal = array[mid];
        if (midVal > v)
            low = mid + 1;
        else if (midVal < v)
            high = mid - 1;
        else
            return mid; // key found
    }
    return low;//traditionally, -(low + 1);  // key not found.
}

private static int[] sortedArrayMerge(int a[], int b[]) {
    int result[] = new int[a.length + b.length];
    int k, i = 0, j = 0;
    if (a[0] > b[0]) {
        k = i = binarySearch(b, 0, b.length, a[0]);
        System.arraycopy(b, 0, result, 0, i);
    } else {
        k = j = binarySearch(a, 0, a.length, b[0]);
        System.arraycopy(a, 0, result, 0, j);
    }
    while (i < a.length && j < b.length) {
        result[k++] = (a[i] < b[j]) ? a[i++] : b[j++];
    }
    if (j < b.length) {
        System.arraycopy(b, j, result, k, (b.length - j));
    } else {
        System.arraycopy(a, i, result, k, (a.length - i));
    }
    return result;
}
2
Tatarize

Voici un formulaire abrégé écrit en javascript:

function sort( a1, a2 ) {

    var i = 0
        , j = 0
        , l1 = a1.length
        , l2 = a2.length
        , a = [];

    while( i < l1 && j < l2 ) {

        a1[i] < a2[j] ? (a.Push(a1[i]), i++) : (a.Push( a2[j]), j++);
    }

    i < l1 && ( a = a.concat( a1.splice(i) ));
    j < l2 && ( a = a.concat( a2.splice(j) ));

    return a;
}
2
swallace

L'algorithme pourrait être amélioré de plusieurs façons. Par exemple, il est raisonnable de vérifier si a[m-1]<b[0] ou b[n-1]<a[0]. Dans aucun de ces cas, il n'est pas nécessaire de faire plus de comparaisons. L’algorithme pourrait simplement copier les tableaux sources dans le résultat, dans le bon ordre.

Des améliorations plus complexes peuvent inclure la recherche de pièces entrelacées et l’exécution d’un algorithme de fusion pour celles-ci uniquement. Il pourrait gagner beaucoup de temps, lorsque la taille des tableaux fusionnés diffère de fois en temps.

1
Hengameh
public static int[] merge(int[] a, int[] b) {
    int[] mergedArray = new int[(a.length + b.length)];
    int i = 0, j = 0;
    int mergedArrayIndex = 0;
    for (; i < a.length || j < b.length;) {
        if (i < a.length && j < b.length) {
            if (a[i] < b[j]) {
                mergedArray[mergedArrayIndex] = a[i];
                i++;
            } else {
                mergedArray[mergedArrayIndex] = b[j];
                j++;
            }
        } else if (i < a.length) {
            mergedArray[mergedArrayIndex] = a[i];
            i++;
        } else if (j < b.length) {
            mergedArray[mergedArrayIndex] = b[j];
            j++;
        }
        mergedArrayIndex++;
    }
    return mergedArray;
}
1
toobsco42

Ce problème est lié à l'algorithme mergesort, dans lequel deux sous-tableaux triés sont combinés en un seul sous-tableau trié. Le livre CLRS donne un exemple de l'algorithme et élimine la nécessité de vérifier si la fin a été atteinte en ajoutant une valeur sentinelle (quelque chose qui compare et "supérieure à toute autre valeur") à la fin de chaque tableau.

Je l'ai écrit en Python, mais cela devrait également se traduire en Java:

def func(a, b):
    class sentinel(object):
        def __lt__(*_):
            return False

    ax, bx, c = a[:] + [sentinel()], b[:] + [sentinel()], []
    i, j = 0, 0

    for k in range(len(a) + len(b)):
        if ax[i] < bx[j]:
            c.append(ax[i])
            i += 1
        else:
            c.append(bx[j])
            j += 1

    return c
1
d11wtq

Vous pouvez utiliser 2 threads pour remplir le tableau résultant, un de l'avant et un de l'arrière.

Cela peut fonctionner sans aucune synchronisation dans le cas de nombres, par exemple. si chaque fil insère la moitié des valeurs.

1
tkruse

Je pense que l'introduction de la liste de saut pour le plus grand tableau trié peut réduire le nombre de comparaisons et accélérer le processus de copie dans le troisième tableau. Cela peut être bon si le tableau est trop énorme.

1
sriragav
    public class Merge {

    // stably merge a[lo .. mid] with a[mid+1 .. hi] using aux[lo .. hi]
    public static void merge(Comparable[] a, Comparable[] aux, int lo, int mid, int hi) {

        // precondition: a[lo .. mid] and a[mid+1 .. hi] are sorted subarrays
        assert isSorted(a, lo, mid);
        assert isSorted(a, mid+1, hi);

        // copy to aux[]
        for (int k = lo; k <= hi; k++) {
            aux[k] = a[k]; 
        }

        // merge back to a[]
        int i = lo, j = mid+1;
        for (int k = lo; k <= hi; k++) {
            if      (i > mid)              a[k] = aux[j++];
            else if (j > hi)               a[k] = aux[i++];
            else if (less(aux[j], aux[i])) a[k] = aux[j++];
            else                           a[k] = aux[i++];
        }

        // postcondition: a[lo .. hi] is sorted
        assert isSorted(a, lo, hi);
    }

    // mergesort a[lo..hi] using auxiliary array aux[lo..hi]
    private static void sort(Comparable[] a, Comparable[] aux, int lo, int hi) {
        if (hi <= lo) return;
        int mid = lo + (hi - lo) / 2;
        sort(a, aux, lo, mid);
        sort(a, aux, mid + 1, hi);
        merge(a, aux, lo, mid, hi);
    }

    public static void sort(Comparable[] a) {
        Comparable[] aux = new Comparable[a.length];
        sort(a, aux, 0, a.length-1);
        assert isSorted(a);
    }


   /***********************************************************************
    *  Helper sorting functions
    ***********************************************************************/

    // is v < w ?
    private static boolean less(Comparable v, Comparable w) {
        return (v.compareTo(w) < 0);
    }

    // exchange a[i] and a[j]
    private static void exch(Object[] a, int i, int j) {
        Object swap = a[i];
        a[i] = a[j];
        a[j] = swap;
    }


   /***********************************************************************
    *  Check if array is sorted - useful for debugging
    ***********************************************************************/
    private static boolean isSorted(Comparable[] a) {
        return isSorted(a, 0, a.length - 1);
    }

    private static boolean isSorted(Comparable[] a, int lo, int hi) {
        for (int i = lo + 1; i <= hi; i++)
            if (less(a[i], a[i-1])) return false;
        return true;
    }


   /***********************************************************************
    *  Index mergesort
    ***********************************************************************/
    // stably merge a[lo .. mid] with a[mid+1 .. hi] using aux[lo .. hi]
    private static void merge(Comparable[] a, int[] index, int[] aux, int lo, int mid, int hi) {

        // copy to aux[]
        for (int k = lo; k <= hi; k++) {
            aux[k] = index[k]; 
        }

        // merge back to a[]
        int i = lo, j = mid+1;
        for (int k = lo; k <= hi; k++) {
            if      (i > mid)                    index[k] = aux[j++];
            else if (j > hi)                     index[k] = aux[i++];
            else if (less(a[aux[j]], a[aux[i]])) index[k] = aux[j++];
            else                                 index[k] = aux[i++];
        }
    }

    // return a permutation that gives the elements in a[] in ascending order
    // do not change the original array a[]
    public static int[] indexSort(Comparable[] a) {
        int N = a.length;
        int[] index = new int[N];
        for (int i = 0; i < N; i++)
            index[i] = i;

        int[] aux = new int[N];
        sort(a, index, aux, 0, N-1);
        return index;
    }

    // mergesort a[lo..hi] using auxiliary array aux[lo..hi]
    private static void sort(Comparable[] a, int[] index, int[] aux, int lo, int hi) {
        if (hi <= lo) return;
        int mid = lo + (hi - lo) / 2;
        sort(a, index, aux, lo, mid);
        sort(a, index, aux, mid + 1, hi);
        merge(a, index, aux, lo, mid, hi);
    }

    // print array to standard output
    private static void show(Comparable[] a) {
        for (int i = 0; i < a.length; i++) {
            StdOut.println(a[i]);
        }
    }

    // Read strings from standard input, sort them, and print.
    public static void main(String[] args) {
        String[] a = StdIn.readStrings();
        Merge.sort(a);
        show(a);
    }
}
1
jackhao
public int[] merge(int[] a, int[] b) {
    int[] result = new int[a.length + b.length];
    int aIndex, bIndex = 0;

    for (int i = 0; i < result.length; i++) {
        if (aIndex < a.length && bIndex < b.length) {
            if (a[aIndex] < b[bIndex]) {
                result[i] = a[aIndex];
                aIndex++;
            } else {
                result[i] = b[bIndex];
                bIndex++;
            }
        } else if (aIndex < a.length) {
            result[i] = a[aIndex];
            aIndex++;
        } else {
            result[i] = b[bIndex];
            bIndex++;
        }
    }

    return result;
}
1
Andrew
//How to merge two sorted arrays into a sorted array without duplicates?
//simple C Coding
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

main()
{
    int InputArray1[] ={1,4,5,7,8,9,12,13,14,17,40};
    int InputArray2[] ={4,5,11,14,15,17,18,19,112,122,122,122,122};
    int n=10;
    int OutputArray[30];
    int i=0,j=0,k=0;
    //k=OutputArray
    while(i<11 && j<13)
    {
        if(InputArray1[i]<InputArray2[j])
        {
            if (k == 0 || InputArray1[i]!= OutputArray[k-1])
            {
                OutputArray[k++] = InputArray1[i];
            }
            i=i+1;
        }
        else if(InputArray1[i]>InputArray2[j])
        {
            if (k == 0 || InputArray2[j]!= OutputArray[k-1])
            {
                OutputArray[k++] = InputArray2[j];
            }
            j=j+1;
        }
        else
        {
            if (k == 0 || InputArray1[i]!= OutputArray[k-1])
            {
                OutputArray[k++] = InputArray1[i];
            }
            i=i+1;
            j=j+1;
        }
    };
    while(i<11)
    {
        if(InputArray1[i]!= OutputArray[k-1])
            OutputArray[k++] = InputArray1[i++];
        else
            i++;
    }
    while(j<13)
    {
        if(InputArray2[j]!= OutputArray[k-1])
            OutputArray[k++] = InputArray2[j++];
        else
            j++;
    }
    for(i=0; i<k; i++)
    {
        printf("sorted data:%d\n",OutputArray[i]);
    };
}
0
Chanchal
var arrCombo = function(arr1, arr2){
  return arr1.concat(arr2).sort(function(x, y) {
    return x - y;
  });
};
0
Alex Hawkins

Pour séparer deux tableaux triés en complexité temporelle O (m + n), utilisez l’approche ci-dessous avec une seule boucle . M et n sont les longueurs des premier et deuxième tableaux.

public class MargeSortedArray {
    public static void main(String[] args) {
        int[] array = new int[]{1,3,4,7};
        int[] array2 = new int[]{2,5,6,8,12,45};
        int[] newarry = margeToSortedArray(array, array2);
        //newarray is marged array
    }

    // marge two sorted array with o(a+n) time complexity
    public static int[] margeToSortedArray(int[] array, int[] array2) {
        int newarrlen = array.length+array2.length;
        int[] newarr = new int[newarrlen];

        int pos1=0,pos2=0;
        int len1=array.length, len2=array2.length;

        for(int i =0;i<newarrlen;i++) {     
            if(pos1>=len1) {
                newarr[i]=array2[pos2];
                pos2++;
                continue;
            }
            if(pos2>=len2) {
                newarr[i]=array[pos1];
                pos1++;
                continue;
            }

            if(array[pos1]>array2[pos2]) {
                newarr[i]=array2[pos2];
                pos2++;
            } else {
                newarr[i]=array[pos1];
                pos1++;
            }   
        }

        return newarr;
    }

}
0
Birbal Singh
public static int[] merge(int[] listA, int[] listB) {
        int[] mergedList = new int[ listA.length + listB.length];
        int i = 0; // Counter for listA
        int j = 0; // Counter for listB
        int k = 0; // Counter for mergedList
        while (true) {
            if (i >= listA.length && j >= listB.length) {
                break;
            }
            if (i < listA.length && j < listB.length) { // If both counters are valid.
                if (listA[i] <= listB[j]) {
                    mergedList[k] = listA[i];
                    k++;
                    i++;
                } else {
                    mergedList[k] = listB[j];
                    k++;
                    j++;
                }
            } else if (i < listA.length && j >= listB.length) { // If only A's counter is valid.
                mergedList[k] = listA[i];
                k++;
                i++;
            } else if (i <= listA.length && j < listB.length) { // If only B's counter is valid
                mergedList[k] = listB[j];
                k++;
                j++;
            }
        }
        return mergedList;
    }
0
Sean Woolfolk
public static int[] mergeSorted(int[] left, int[] right) {
    System.out.println("merging " + Arrays.toString(left) + " and " + Arrays.toString(right));
    int[] merged = new int[left.length + right.length];
    int nextIndexLeft = 0;
    int nextIndexRight = 0;
    for (int i = 0; i < merged.length; i++) {
        if (nextIndexLeft >= left.length) {
            System.arraycopy(right, nextIndexRight, merged, i, right.length - nextIndexRight);
            break;
        }
        if (nextIndexRight >= right.length) {
            System.arraycopy(left, nextIndexLeft, merged, i, left.length - nextIndexLeft);
            break;
        }
        if (left[nextIndexLeft] <= right[nextIndexRight]) {
            merged[i] = left[nextIndexLeft];
            nextIndexLeft++;
            continue;
        }
        if (left[nextIndexLeft] > right[nextIndexRight]) {
            merged[i] = right[nextIndexRight];
            nextIndexRight++;
            continue;
        }
    }
    System.out.println("merged : " + Arrays.toString(merged));
    return merged;
}

Juste un petit différent de la solution originale

0

Mon langage de programmation préféré est JavaScript

function mergeSortedArrays(a, b){
    var result = [];

    var sI = 0;
    var lI = 0;
    var smallArr;
    var largeArr;
    var temp;

    if(typeof b[0] === 'undefined' || a[0]<b[0]){
        smallArr = a;
        largeArr = b;
    } else{
        smallArr = b;
        largeArr = a;
    }

    while(typeof smallArr[sI] !== 'undefined'){
        result.Push(smallArr[sI]);
        sI++;

        if(smallArr[sI]>largeArr[lI] || typeof smallArr[sI] === 'undefined'){
            temp = smallArr;
            smallArr = largeArr;
            largeArr = temp;
            temp = sI;
            sI = lI;
            lI = temp;
        }
    }
    return result;
}
0
Saad Ahmed

Vous pouvez utiliser des opérateurs ternaires pour rendre le code un peu plus compact.

public static int[] mergeArrays(int[] a1, int[] a2) {
    int[] res = new int[a1.length + a2.length];
    int i = 0, j = 0;

    while (i < a1.length && j < a2.length) {
        res[i + j] = a1[i] < a2[j] ? a1[i++] : a2[j++];
    }

    while (i < a1.length) {
        res[i + j] = a1[i++];
    }

    while (j < a2.length) {
        res[i + j] = a2[j++];
    }

    return res;
}
0
Jenna Kwon
var arr1 = [2,10,20,30,100];
var arr2 = [2,4,5,6,7,8,9];
var j = 0;
var i =0;
var newArray = [];

for(var x=0;x< (arr1.length + arr2.length);x++){
    if(arr1[i] >= arr2[j]){                //check if element arr2 is equal and less than arr1 element
        newArray.Push(arr2[j]);
      j++;
    }else if(arr1[i] < arr2[j]){            //check if element arr1 index value  is less than arr2 element
        newArray.Push(arr1[i]);
        i++;
    }
    else if(i == arr1.length || j < arr2.length){    // add remaining arr2 element
        newArray.Push(arr2[j]);
        j++
    }else{                                                   // add remaining arr1 element
        newArray.Push(arr1[i]); 
        i++
    }

}

console.log(newArray);
0
Amar1990
public static void main(String[] args) {
    int[] arr1 = {2,4,6,8,10,999};
    int[] arr2 = {1,3,5,9,100,1001};

    int[] arr3 = new int[arr1.length + arr2.length];

    int temp = 0;

    for (int i = 0; i < (arr3.length); i++) {
        if(temp == arr2.length){
            arr3[i] = arr1[i-temp];
        }
        else if (((i-temp)<(arr1.length)) && (arr1[i-temp] < arr2[temp])){
                arr3[i] = arr1[i-temp];
        }
        else{
            arr3[i] = arr2[temp];
            temp++;
        }
    }

    for (int i : arr3) {
        System.out.print(i + ", ");
    }
}

La sortie est:

1, 2, 3, 4, 5, 6, 8, 9, 10, 100, 999, 1001, 

0
Rajesh Gurbani

Peut-être utiliser System.arraycopy

public static byte[] merge(byte[] first, byte[] second){
    int len = first.length + second.length;
    byte[] full = new byte[len];
    System.arraycopy(first, 0, full, 0, first.length);
    System.arraycopy(second, 0, full, first.length, second.length);
    return full;
}
0
nurisezgin