Algorithm

Merge Sort

Sorting Pattern

Merge Sort

Given an unsorted array of integers, sort the array in ascending order using the Merge Sort algorithm. Merge Sort is a divide-and-conquer algorithm that works by recursively splitting the array into halves, sorting them, and then merging them back together.

CONSTRAINTS
  • 1 ≤ nums.length ≤ 5 * 10⁴
  • -5 * 10⁴ ≤ nums[i] ≤ 5 * 10⁴
  • Space Complexity: O(N) for temporary arrays
  • Time Complexity: O(N log N) guaranteed
EXAMPLE 1
Input: nums = [38, 27, 43, 3, 9, 82, 10]
Output: [3, 9, 10, 27, 38, 43, 82]
The array is divided until single elements remain, then merged back in sorted order.
EXAMPLE 2
Input: nums = [1, 2, 3, 4]
Output: [1, 2, 3, 4]
Even if the array is already sorted, Merge Sort still performs the full divide and merge process (O(N log N)).
EXAMPLE 3
Input: nums = [4, 3, 2, 1]
Output: [1, 2, 3, 4]
Merge Sort handles reverse sorted data as efficiently as any other case.
Do we need to maintain the relative order of duplicate elements?
Yes, preserving the original order of equal elements (stability) is a requirement.
Could the input be a very large array that doesn't fit in cache?
The algorithm should be efficient for large datasets, though you can assume the entire array fits in main memory.
The Strategy: Divide and Conquer

Merge Sort is the classic example of the Divide and Conquer paradigm. While Quick Sort does the "hard work" during the partitioning (splitting) phase, Merge Sort does its heavy lifting during the Merge (combining) phase. The core insight is that it is computationally easier to merge two already-sorted lists than it is to sort one large, unsorted one.

The Execution: The Recursive Split

The algorithm starts by taking the array and cutting it exactly in half. It then calls itself recursively on both halves. This process repeats until the array is broken down into single-element sub-arrays.
- A single element is, by definition, already sorted.
- This serves as our base case, where the recursion stops and the "merging" begins.

The Merge: Ordering the Chaos

Once we have two sorted halves, we combine them into a single sorted result using a two-pointer approach:
1. We compare the first element of the Left half with the first element of the Right half.
2. We take the smaller element and place it into a temporary result array.
3. We move the pointer forward in the half from which we took the element.
4. We repeat this until one half is exhausted, then append all remaining elements from the other half.

Because we always pick the element from the Left half first when values are equal, Merge Sort is naturally stable—it preserves the original relative order of duplicate elements.

Why Use Merge Sort?

- Guaranteed Performance: Unlike Quick Sort, which can degrade to O(N^2) if the pivot selection is poor, Merge Sort is strictly O(N log N) in all cases (Best, Average, and Worst).
- Stability: It is the default choice when you need to maintain the order of equal elements (e.g., sorting a list of transactions by "Amount" without shuffling their original "Timestamp" order).
- Linked Lists: Because it accesses data sequentially rather than randomly, it is the most efficient algorithm for sorting linked lists where random access is expensive.

Avoid it when:
- Memory is limited: Merge Sort is not "in-place." It requires O(N) extra space to store the temporary merged arrays, which can be a bottleneck for extremely large datasets.

Pseudo Code
text
FUNCTION mergesort(arr):
    IF length < 2: RETURN arr
    mid = length / 2
    left = mergesort(arr[0...mid])
    right = mergesort(arr[mid...end])
    RETURN merge(left, right)

FUNCTION merge(left, right):
    result = []
    WHILE left and right both have elements:
        IF left[0] <= right[0]: 
            ADD left[0] to result
            REMOVE left[0]
        ELSE: 
            ADD right[0] to result
            REMOVE right[0]
    ADD remaining elements from either list to result
Walkthrough:[38, 27, 43, 3]
1. Split: [38, 27, 43, 3] → [38, 27] and [43, 3].
2. Split again: [38], [27], [43], [3].
3. Merge: Compare [38] and [27] → [27, 38]. Compare [43] and [3] → [3, 43].
4. Final Merge: Compare [27, 38] and [3, 43].
- 27 vs 3 → [3]
- 27 vs 43 → [3, 27]
- 38 vs 43 → [3, 27, 38]
- Append remaining → [3, 27, 38, 43].
Key Traits

- Stability: Yes (equal elements preserve their relative order).
- In-Place: No (requires O(N) extra space).
- Time Complexity: O(N log N) guaranteed (best, average, and worst).

Interactive Strategy Visualization

DIVIDE & CONQUER STRATEGY

Visualizing the recursive tree structure.

38
27
43
3
Original Array

We start with an unsorted list. The goal is to sort it using the 'Divide & Conquer' strategy.

SORTING
SORTED / BASE
O(N²) Bubble Sort
O(N log N) Merge Sort (Guaranteed)