87. First Missing Positive
hardAsked at SalesforceFind the smallest positive integer missing from an unsorted array in O(n) time and O(1) space. Salesforce uses this as an O(1)-space cyclic-sort stress test.
By Alex Chen, Founder, InterviewChamp.AI · Last verified
Source citations
Public interview reports confirming this problem appears in Salesforce loops.
- Glassdoor (2026-Q1)— Salesforce uses cyclic sort in their ID-assignment logic for new records.
- Blind (2025-09)— Hard L5+ onsite question.
Problem
Given an unsorted integer array nums. Return the smallest positive integer that is not present in nums. You must implement an algorithm that runs in O(n) time and uses O(1) auxiliary space.
Constraints
1 <= nums.length <= 10^5-2^31 <= nums[i] <= 2^31 - 1
Examples
Example 1
nums = [1,2,0]3Example 2
nums = [3,4,-1,1]2Example 3
nums = [7,8,9,11,12]1Approaches
1. Set lookup
Insert all values into a set; check 1, 2, 3, ... until missing.
- Time
- O(n)
- Space
- O(n)
function firstMissingPositive(nums) {
const set = new Set(nums);
for (let i = 1; i <= nums.length + 1; i++) if (!set.has(i)) return i;
}Tradeoff: O(n) space — fails the explicit constraint.
2. Cyclic sort in place
For each position i, swap nums[i] to its correct position (nums[i] - 1) if valid. Then scan: first index where nums[i] !== i+1 is the answer.
- Time
- O(n)
- Space
- O(1)
function firstMissingPositive(nums) {
const n = nums.length;
for (let i = 0; i < n; i++) {
while (nums[i] > 0 && nums[i] <= n && nums[nums[i] - 1] !== nums[i]) {
[nums[i], nums[nums[i] - 1]] = [nums[nums[i] - 1], nums[i]];
}
}
for (let i = 0; i < n; i++) if (nums[i] !== i + 1) return i + 1;
return n + 1;
}Tradeoff: O(1) extra space. The cyclic-sort puts each valid value at its 'natural' index. Salesforce's preferred answer.
Salesforce-specific tips
Salesforce uses cyclic sort in their ID-assignment logic — find the smallest available ID in a bounded range without an external counter. They specifically grade on whether you can articulate WHY swapping works (each swap places one element correctly, so total swaps are at most n). Bonus signal: explain the amortized O(n) bound.
Common mistakes
- Using if instead of while — only one swap per position; misses subsequent good swaps.
- Forgetting the `nums[nums[i] - 1] !== nums[i]` check — infinite loop on duplicates.
- Skipping bounds checks (1 <= nums[i] <= n) — out-of-bounds access.
Follow-up questions
An interviewer at Salesforce may pivot to one of these next:
- Find All Numbers Disappeared in an Array (LC 448) — same cyclic-sort pattern.
- Find the Duplicate Number (LC 287).
- First Missing Positive in a stream.
Solve it now
Free. No sign-up. Python and JavaScript run instantly in your browser.
FAQ
Why O(n) despite the while loop?
Amortized analysis: each swap places at least one element at its correct position. Over the whole loop, at most n swaps happen. The while ensures we keep working until the current position is settled.
Why ignore negatives and >n values?
The answer is in [1, n+1]. Values outside that range can't be the answer and can be ignored during placement.
Practice these live with InterviewChamp.AI
Drill First Missing Positive and other Salesforce interview questions under real-loop conditions with instant feedback on your reasoning, complexity claims, and code.
Practice these live with InterviewChamp.AI →