DrawCode Algorithm Visualizer • Divide and Conquer • Medium

Quick Select

Tags: Divide and Conquer, Order Statistics, Median, Partition

1. One-Liner

Quickselect finds the k-th smallest element by partitioning once and recursing only into the half that contains the answer—like binary search on a pivot layout.


2. The Problem It Solves

You need the median, percentiles, or top-k elements without sorting the entire array (O(n log n)). Average time drops to O(n) when partitions are balanced enough.


3. The Core Idea

Pick a pivot, partition so smaller elements are left and larger are right. If the pivot lands at index k, you are done; else recurse left or right only—one subproblem, not two.


4. How It Works (Step-by-Step)

StepWhat Happens
1. Choose pivotOften last element or random for balance.
2. PartitionLomuto/Hoare: place pivot in sorted position p.
3. CompareIf p == k, return a[p].
4. RecurseIf k < p, search left; else search right with adjusted k.

5. Dry Run Example

Array: [7, 2, 1, 6, 8], k = 2 (0-based 2nd smallest → 6 is wrong; smallest index 2 → third smallest). After partition, pivot index tells which side holds k.


6. Key Properties

PropertyValue
Average timeO(n) expected
Worst caseO() with bad pivots
SpaceO(1) iterative + recursion stack
In-placeYes with array partitioning

7. Where It Is Used

DomainUse
StatisticsMedian, quantiles on streams
Librariesnth_element in C++, selection in standard libs

8. Interview Tips

Relate to quicksort but single recursion; mention random pivot or median-of-medians for worst-case guarantees.


9. Comparison with Other Algorithms

ApproachTimeNotes
QuickselectO(n) avgIn-place
Sort + indexO(n log n)Simpler, more work
Heap (k small)O(n log k)Good for top-k heap

10. Complexity

MetricValue
Time (Average)O(n)
Time (Worst)O() naive pivot
SpaceO(log n) stack typical

Implementation Example (PYTHON)

import random

def quick_select(nums, k):
    def partition(lo, hi):
        piv = random.randint(lo, hi)
        nums[piv], nums[hi] = nums[hi], nums[piv]
        store = lo
        for i in range(lo, hi):
            if nums[i] < nums[hi]:
                nums[store], nums[i] = nums[i], nums[store]
                store += 1
        nums[store], nums[hi] = nums[hi], nums[store]
        return store
    lo, hi = 0, len(nums) - 1
    while True:
        p = partition(lo, hi)
        if p == k: return nums[p]
        if k < p: hi = p - 1
        else: lo = p + 1

Interactive Visualizer Workspace

Explore step-by-step interactive animations, memory state tracking, and live multi-language execution in DrawCode.

Launch Interactive Visualizer