Skip to main content

LeetCode Patterns

Cyclic Sort Pattern

Cyclic Sort places each value in an array of integers from a known range into its correct index by swapping it with whatever value is currently there. It is the canonical pattern for problems on arrays containing numbers in the range 1..n or 0..n-1 and runs in O(n) time with O(1) extra space.

By Alex Chen, Founder, InterviewChamp.AI · Last verified

Complexity

Time
O(n)
Space
O(1)

When to use Cyclic Sort

  • The array contains exactly n elements drawn from the range 1..n or 0..n-1 (with at most one duplicate or one missing).
  • You need to find the missing, duplicate, or first-positive-missing number in O(1) extra space.
  • Hash-set and counting-array approaches are disqualified by an explicit space constraint.
  • The problem mentions that numbers correspond to indices, like `nums[i] = i + 1`.
  • Sorting the array is sufficient to derive the answer in a single follow-up pass.

Template

function cyclicSort(nums) {
  let i = 0;
  while (i < nums.length) {
    const correctIndex = nums[i] - 1;
    if (nums[i] !== nums[correctIndex]) {
      [nums[i], nums[correctIndex]] = [nums[correctIndex], nums[i]];
    } else {
      i++;
    }
  }
  return nums;
}

Example LeetCode problems

#ProblemDifficultyFrequency
268Missing Numbereasyfoundational
448Find All Numbers Disappeared in an Arrayeasyfoundational
287Find the Duplicate Numbermediumcompany favorite
442Find All Duplicates in an Arraymediumfrequently asked
41First Missing Positivehardcompany favorite
645Set Mismatcheasyclassic

Common mistakes

  • Incrementing `i` inside the swap branch, which skips over the value you just placed and leaves the new value unprocessed.
  • Comparing `nums[i] === correctIndex` (an index-vs-value mix-up) instead of `nums[i] === nums[correctIndex]`.
  • Using Cyclic Sort on input ranges that are not 1..n or 0..n-1, where the index mapping breaks down.
  • Forgetting to guard against out-of-range values in First Missing Positive — values outside 1..n must be ignored, not placed.
  • Returning the partially-sorted array from inside the swap loop before completing all placements.

Frequently asked questions

Why is Cyclic Sort O(n) when it contains a while loop with a swap inside?

Each successful swap moves a value to its final index, so the total number of swaps across the entire algorithm is bounded by n. The other branch increments i, also bounded by n. Total work is O(n).

When is Cyclic Sort better than just calling the built-in sort?

Cyclic Sort runs in linear time and constant space; comparison sorts are O(n log n). It also gives you the placement positions for free, which makes follow-up questions (find duplicates, missing numbers) trivial.

Does it work with duplicates?

Yes. The termination condition `nums[i] !== nums[correctIndex]` skips swaps when the value is already in its correct position OR a duplicate already occupies that position. After the loop, indices where `nums[i] !== i + 1` reveal both missing and duplicate values.

Can I use this for 1-indexed arrays?

Yes — adjust the correctIndex formula to `nums[i]` (for 0..n-1 ranges) or `nums[i] - 1` (for 1..n ranges). Pick one convention and stay consistent across the loop and the final scan.

Solve it now

Free. No sign-up. Python and JavaScript run instantly in your browser.

Output

Press Run or Cmd+Enter to execute

Practice these live with InterviewChamp.AI

Drill the Cyclic Sort pattern under real interview conditions with instant feedback on your reasoning, complexity claims, and code.

Practice these live with InterviewChamp.AI →