Skip to content
intermediate Phase 3 · Sorting & Searching

Quick Sort

Learn efficient in-place sorting with average O(n log n) performance.

1h
4 problems
Topic Progress 0%

Quick Sort Fundamentals

Quick sort is a divide-and-conquer algorithm that picks a pivot, partitions array around it, then recursively sorts subarrays.

Algorithm Steps

  1. Choose Pivot: Select an element (first, last, random, or median)
  2. Partition: Rearrange so elements < pivot are left, elements > pivot are right
  3. Recurse: Recursively sort left and right partitions

Visual Example

Array: [3, 6, 8, 10, 1, 2, 1]
Pivot: 10 (last element)

Partition:
[3, 6, 8, 1, 2, 1] [10]
(< pivot)            (pivot)

Recurse on left:
[3, 6, 8, 1, 2, 1]
Pivot: 1
[1] [3, 6, 8, 2] [1]

Continue until sorted: [1, 1, 2, 3, 6, 8, 10]

Lomuto Partition Scheme

public void quickSort(int[] arr, int low, int high) {
    if (low < high) {
        int pivotIndex = partition(arr, low, high);
        quickSort(arr, low, pivotIndex - 1);
        quickSort(arr, pivotIndex + 1, high);
    }
}

private int partition(int[] arr, int low, int high) {
    int pivot = arr[high];  // Choose last element as pivot
    int i = low - 1;       // Pointer for smaller elements
    
    for (int j = low; j < high; j++) {
        if (arr[j] <= pivot) {
            i++;
            swap(arr, i, j);
        }
    }
    
    swap(arr, i + 1, high);  // Place pivot in correct position
    return i + 1;
}

private void swap(int[] arr, int i, int j) {
    int temp = arr[i];
    arr[i] = arr[j];
    arr[j] = temp;
}

Hoare Partition Scheme

More efficient, swaps fewer elements:

public void quickSortHoare(int[] arr, int low, int high) {
    if (low < high) {
        int pivotIndex = partitionHoare(arr, low, high);
        quickSortHoare(arr, low, pivotIndex);
        quickSortHoare(arr, pivotIndex + 1, high);
    }
}

private int partitionHoare(int[] arr, int low, int high) {
    int pivot = arr[low + (high - low) / 2];
    int i = low - 1;
    int j = high + 1;
    
    while (true) {
        do { i++; } while (arr[i] < pivot);
        do { j--; } while (arr[j] > pivot);
        
        if (i >= j) return j;
        swap(arr, i, j);
    }
}

Randomized Quick Sort

Avoids worst-case by random pivot selection:

private int partitionRandom(int[] arr, int low, int high) {
    int random = low + (int)(Math.random() * (high - low + 1));
    swap(arr, random, high);
    return partition(arr, low, high);
}

Complexity Analysis

Case Time Space When
Best O(n log n) O(log n) Pivot always divides evenly
Average O(n log n) O(log n) Random input
Worst O(n²) O(n) Already sorted (with bad pivot)

Quick Select (Selection Algorithm)

Quick select is a variation of quicksort that finds the kth smallest element without fully sorting the array.

Algorithm

  1. Partition around pivot
  2. If pivot index equals k, return pivot
  3. If k < pivot index, recurse on left partition
  4. If k > pivot index, recurse on right partition

Java Implementation

public int quickSelect(int[] arr, int k) {
    return quickSelect(arr, 0, arr.length - 1, k - 1);
}

private int quickSelect(int[] arr, int low, int high, int k) {
    if (low == high) return arr[low];
    
    int pivotIndex = partition(arr, low, high);
    
    if (k == pivotIndex) {
        return arr[k];
    } else if (k < pivotIndex) {
        return quickSelect(arr, low, pivotIndex - 1, k);
    } else {
        return quickSelect(arr, pivotIndex + 1, high, k);
    }
}

Iterative Quick Select

public int quickSelectIterative(int[] arr, int k) {
    int low = 0, high = arr.length - 1;
    
    while (low <= high) {
        int pivotIndex = partition(arr, low, high);
        
        if (pivotIndex == k) {
            return arr[k];
        } else if (pivotIndex < k) {
            low = pivotIndex + 1;
        } else {
            high = pivotIndex - 1;
        }
    }
    
    throw new IllegalArgumentException("k is out of bounds");
}

Applications of Quick Select

  1. Find kth largest/smallest element
  2. Median finding
  3. Top k elements (with partial sort)
  4. Statistics (percentiles, quartiles)

Complexity

Case Time Space
Best O(n) O(1)
Average O(n) O(1)
Worst O(n²) O(n)

When to Use Quick Select

  • Finding single element (kth smallest/largest)
  • Finding median
  • Don't need full sort
  • Memory is limited

Interactive Visualization

Quick Sort Partitioning

Press Play or Step to begin
Current Found / Done Eliminated Unvisited

Practice Problems

0 / 4 solved
Sort Colors (Dutch National Flag)
Three-Way Partition

Given an array with objects colored red, white, or blue (0, 1, 2), sort them in-place.

Example:

Input: nums = [2,0,2,1,1,0]

Output: [0,0,1,1,2,2]

Three-way partition.

Edge Cases:

  • All 0s: already sorted
  • All 2s: all swap to the right
  • Single element: no changes needed
  • Two elements: may need one swap
Kth Largest Element in an Array
Heap

Given an integer array nums and an integer k, return the kth largest element in the array. Note: it is the kth largest element in sorted order, not the kth distinct element.

Example:

Input: nums = [3,2,1,5,6,4], k = 2

Output: 5

The 2nd largest element is 5 (sorted: [1,2,3,4,5,6]).

Edge Cases:

  • k equals array length — answer is the minimum element
  • k equals 1 — answer is the maximum element
  • All elements same value
  • Negative numbers present
  • Single element array
Top K Frequent Elements
Bucket Sort

Given an integer array nums and an integer k, return the k most frequent elements.

Example:

Input: nums = [1,1,1,2,2,3], k = 2

Output: [1,2]

1 appears 3 times, 2 appears 2 times.

Edge Cases:

  • k equals number of unique elements
  • All elements same
  • All elements unique
  • k = 1
  • Negative numbers
Kth Largest Element in an Array
Quick Select

Given an integer array nums and an integer k, return the kth largest element.

Example:

Input: nums = [3,2,1,5,6,4], k = 2

Output: 5

Second largest is 5.

Edge Cases:

  • k = 1: return the maximum
  • k = n: return the minimum
  • All elements same: return that element

Quiz

1. What causes quicksort's worst-case O(n²) time complexity?

Question 1 options

2. What is the space complexity of quicksort?

Question 2 options

3. What is a common mistake when implementing Quick Sort?

Question 3 options

Flashcards

Question

What is the average time complexity of quicksort?

Answer

O(n log n) - with good pivot selection, array is divided roughly in half each time.

Question

How does randomized quicksort avoid worst-case?

Answer

By randomly selecting pivot, we avoid consistent bad partitions that occur with deterministic pivot choices on sorted data.

Question

Quick Sort best practices

Answer

Follow SOLID principles, write clean code, test thoroughly, document decisions, and monitor in production.

Revision Notes

Key Takeaways

  • 1. Quicksort is fast in practice despite O(n²) worst case
  • 2. Pivot selection strategy is critical for performance
  • 3. Randomized quicksort avoids worst-case on sorted data
  • 4. Quick select finds kth element in O(n) average time

Interview Tips

  • Discuss pivot selection strategies and their tradeoffs
  • Explain why quicksort is often preferred over merge sort in practice
  • Mention quick select for kth element problems
  • Know both Lomuto and Hoare partition schemes

Cheat Sheet

Quick Sort Cheat Sheet

Algorithm:

  1. Choose pivot element
  2. Partition: elements < pivot left, > pivot right
  3. Recursively sort partitions

Partition (Lomuto):

int partition(int[] arr, int low, int high) {
    int pivot = arr[high];
    int i = low - 1;
    for (int j = low; j < high; j++) {
        if (arr[j] <= pivot) swap(arr, ++i, j);
    }
    swap(arr, i + 1, high);
    return i + 1;
}

Complexity:

  • Time: O(n log n) avg, O(n²) worst
  • Space: O(log n) avg
  • Stable: No

Optimizations:

  • Randomized pivot
  • Median-of-three
  • Insertion sort for small subarrays