Cyclic Sort
The Cyclic Sort pattern is an efficient technique used primarily for problems involving arrays containing numbers in a given range. Typically, if an array of length n
contains numbers from 1
to n
(or 0
to n-1
), Cyclic Sort can be used to arrange these numbers into their correct sorted positions in linear time.
Core Idea:
The main idea is to iterate through the array, and for each element, place it at its correct index. If the element at the current index i
is x
, its correct position should be at index x-1
(if the numbers are from 1
to n
) or x
(if numbers are from 0
to n-1
).
- Iterate through the array, element by element.
- For the current element
nums[i]
, determine its correct position, let’s sayj
. - If
nums[i]
is not already atnums[j]
, swapnums[i]
withnums[j]
. - Repeat step 3 for the new
nums[i]
(the element that was swapped into this position) untilnums[i]
is the correct element for indexi
(i.e.,nums[i] == i+1
ornums[i] == i
). - Only then move to the next index
i+1
.
This process continues until all numbers are in their correct sorted positions. Because each number is placed in its correct spot at most once, the overall time complexity is O(n).
Common Scenarios & How it Works:
- Sorting an Array with Numbers in a Specific Range:
- When you have an array of
n
numbers and you know these numbers are in the range[1, n]
or[0, n-1]
(possibly with duplicates or missing numbers). - The goal is to sort the array. After applying Cyclic Sort, the element
k
will be at indexk-1
(ork
).
- When you have an array of
- Finding the Missing Number:
- Given an array of
n-1
numbers from the range[1, n]
, find the missing number. - Apply Cyclic Sort. After sorting, iterate through the array. The first index
i
wherenums[i] != i+1
indicates thati+1
is the missing number. If all numbers are in place, the missing number isn
.
- Given an array of
- Finding All Missing Numbers:
- Similar to finding one missing number, but you collect all indices
i
wherenums[i] != i+1
.
- Similar to finding one missing number, but you collect all indices
- Finding the Duplicate Number:
- If an array of
n+1
numbers contains numbers from[1, n]
with one duplicate. - During Cyclic Sort, if you encounter
nums[i]
and find thatnums[i]
is already present at its correct positionnums[nums[i]-1]
, thennums[i]
is the duplicate. (Careful with the condition to avoid infinite loops ifnums[i] == nums[nums[i]-1]
). - Alternatively, after Cyclic Sort, the number at an index
i
that is noti+1
and whose value is already at its correct position indicates a duplicate.
- If an array of
- Finding All Duplicate Numbers:
- Similar to finding one duplicate, but collect all such numbers.
- Finding the Smallest Missing Positive Number (LeetCode #41):
- A more complex variation where the array can contain negative numbers and numbers larger than
n
. You first might need to segregate positive numbers and then apply Cyclic Sort to the relevant part of the array.
- A more complex variation where the array can contain negative numbers and numbers larger than
Advantages:
- Efficiency: Typically achieves O(n) time complexity.
- In-Place: Usually sorts the array with O(1) extra space.
- Simplicity: The core logic of placing elements in their correct positions is relatively intuitive.
When to Use:
- When you are given an array of numbers that should ideally fall into a consecutive range (e.g.,
1
ton
). - Problems that ask to find missing numbers, duplicate numbers, or to sort an array with these specific range properties.
- When an in-place sort with O(n) time complexity is desired for such specific arrays.
Example LeetCode Problems:
- (#268) Missing Number
- (#448) Find All Numbers Disappeared in an Array
- (#287) Find the Duplicate Number
- (#442) Find All Duplicates in an Array
- (#41) First Missing Positive (More advanced, requires careful handling)
- (#645) Set Mismatch (Find the duplicate and the missing number)
- (#765) Couples Holding Hands (Can be modeled as a cyclic sort problem)