DAY 8 / 30 · WEEK 2 · PART 2 OF 3

Selection Sort

← Part 1: Bubble Sort · Selection Sort (here) · Part 3: Insertion Sort →

Goal of the day

Concept

Scan the entire unsorted portion of a hand of cards to find the smallest one, then swap it into the very front position. Now the front card is locked in forever — scan the remaining unsorted portion for its minimum, swap that into the second position, and so on. Unlike bubble sort's "compare and swap next-door neighbors" motion, selection sort scans the whole remaining range every single pass, but only ever swaps once per pass — right at the end, once the minimum is found.

Diagram

Scan for the minimum, swap it to the front 1 2 8 5 9 ← 1 found as the minimum, swapped to index 0 Every pass scans the entire remaining unsorted range — but swaps at most once, right at the end of the scan.

Interactive visualization

comparing current minimum swapping in final position
Press Play or Step to begin.

The code

function selectionSort(arr) {
  for (let i = 0; i < arr.length - 1; i++) {
    let minIdx = i;
    for (let j = i + 1; j < arr.length; j++) {
      if (arr[j] < arr[minIdx]) minIdx = j;
    }
    if (minIdx !== i) [arr[i], arr[minIdx]] = [arr[minIdx], arr[i]];
  }
  return arr;
}

Line by line:

Dry run: selectionSort([5, 2, 8, 1])

iScan finds minSwapArray after
01 (index 3)swap(0, 3)[1, 2, 8, 5]
12 (index 1)no swap needed[1, 2, 8, 5]
25 (index 3)swap(2, 3)[1, 2, 5, 8]

Only 2 swaps total for 4 elements — bubble sort would typically need more, since it swaps on nearly every out-of-order comparison.

Complexity

Time (best)Time (worst)SpaceStable?
O(n²) — always fully scans, even if sortedO(n²)O(1)No

Unlike bubble or insertion sort, selection sort has no fast path for nearly-sorted input — it always scans the full remaining range on every pass, whether or not that scan finds anything to change.

Interview corner

How to talk through it out loud: state the invariant — "after pass i, the first i elements are the i smallest elements in the array, in sorted order." Naming that invariant is what shows you understand why the algorithm is correct, not just that you memorized the loop shape.

Practice problems

1. Third Maximum Number (Easy — LeetCode: Third Maximum Number)

Given an array of integers, return the third distinct maximum value. If it doesn't exist, return the maximum value.

2. Maximum Product of Two Elements in an Array (Easy — LeetCode: Maximum Product of Two Elements in an Array)

Given an array, find the two largest values and return (max1 − 1) × (max2 − 1).

3. Kth Largest Element in an Array (Medium — LeetCode: Kth Largest Element in an Array)

Find the kth largest element in an unsorted array.

Quiz

1. Compared to bubble sort, selection sort minimizes:

2. What's selection sort's BEST-CASE time complexity?

3. Is naive (swap-based) selection sort stable?

4. What does minIdx track in the inner loop?

5. Selection sort's low swap count matters most when:

Continue to Part 3: Insertion Sort →