Merge Sort

medium Searching and Sorting

Problem

Read an array and print it sorted in ascending order. Use merge sort.

Constraints

  • 1 <= n <= 10^5

Examples

Input

6
5 2 9 1 5 6

Output

1 2 5 5 6 9

Solutions

Best approachTime O(n log n)Space O(n)

Divide and conquer: split in two halves, sort each half (by the same method) and merge the sorted halves. The depth is log n and each level costs O(n).

Same code works in Java810172125Basic features only, so nothing changes between versions.
/*
 * Problem : Sort an array in ascending order.
 * Input   : n, then n integers.
 * Output  : The sorted array.
 * Approach: Divide, sort, merge.
 * Time    : O(n log n)
 * Space   : O(n)
 * Java    : 8 or newer.
 */
import java.util.Scanner;
import java.util.Arrays;
import java.util.stream.Collectors;

public class Main {
        // This method merges two sorted halves a[low..mid] and a[mid+1..high] into one sorted part.
        static void merge(int[] a, int low, int mid, int high) {
            int[] left = java.util.Arrays.copyOfRange(a, low, mid + 1);
            int[] right = java.util.Arrays.copyOfRange(a, mid + 1, high + 1);
            int i = 0;
            int j = 0;
            int k = low;

            // Step 3: Always take the smaller front value of the two halves.
            while (i < left.length && j < right.length) {
                if (left[i] <= right[j]) {
                    a[k++] = left[i++];
                } else {
                    a[k++] = right[j++];
                }
            }

            // Step 4: Copy what is left in one of the halves.
            while (i < left.length) {
                a[k++] = left[i++];
            }
            while (j < right.length) {
                a[k++] = right[j++];
            }
        }

        // This method sorts a[low..high]. It splits the range into two halves, sorts each half and merges them.
        static void mergeSort(int[] a, int low, int high) {
            // Step 1: A range with 0 or 1 element is already sorted.
            if (low >= high) {
                return;
            }

            // Step 2: Sort the left half and the right half, then merge them.
            int mid = low + (high - low) / 2;
            mergeSort(a, low, mid);
            mergeSort(a, mid + 1, high);
            merge(a, low, mid, high);
        }

    // This method solves the task. It receives the input and returns the answer.
    static int[] solve(int[] a) {
        mergeSort(a, 0, a.length - 1);
        return a;
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int size = scanner.nextInt();
        int[] a = new int[size];
        for (int i = 0; i < size; i++) {
            a[i] = scanner.nextInt();
        }
        System.out.println(Arrays.stream(solve(a)).mapToObj(String::valueOf).collect(Collectors.joining(" ")));
    }
}
Hints (1)
  1. How do you merge two sorted lists?