Missing Number

82.4k
0

Given an array nums containing n distinct integers taken from the range 0 to n, return the single number from this range that is missing from the array.

Example 1

Input: nums = [3, 0, 1]

Output: 2

Explanation:
The complete range is from 0 to 3: [0, 1, 2, 3].
The number 2 is missing from the array.

Example 2

Input: nums = [9, 6, 4, 2, 3, 5, 7, 0, 1]

Output: 8

Explanation:
The complete range is from 0 to 9.
Every number is present except 8.

Brute Force Approach

Since the array contains every value from 0 to n except one, sorting places the existing values in their expected order.

After sorting, the value at index i should normally be i. Therefore, the first index where nums[i] != i identifies the missing number. If every index matches, then all values from 0 to n - 1 are present, so n must be missing.

Algorithm

  • Store the size of nums in n, which also represents the largest possible value in the expected range.

  • Sort nums in ascending order so each present value can be compared with its expected index.

  • Traverse indices from 0 to n - 1.

  • If nums[i] != i, return i because that expected value is missing from the sorted sequence.

  • If no mismatch is found, return n because all values from 0 to n - 1 are present.

Dry Run

Missing Number Brute Force Approach Dry Run .png

Missing Number Brute Force Approach Dry Run .png

Solution

#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
int missingNumber(vector<int>& nums) {
int n = nums.size();
/*
* Sorting places each present value near its expected
* index, so the first mismatch reveals the missing value.
*/
sort(nums.begin(), nums.end());
for (int i = 0; i < n; i++) {
if (nums[i] != i) {
return i;
}
}
/*
* If every index from 0 to n - 1 matches,
* the only missing value from the range is n.
*/
return n;
}
};
int main() {
vector<int> nums = {3, 0, 1};
Solution solution;
cout << solution.missingNumber(nums) << endl;
return 0;
}

Complexity Analysis

Time Complexity: O(N log N), because sorting dominates the O(N) traversal.

Space Complexity: Depends on the sorting implementation. An in-place sort may use only auxiliary stack space, while some language/library sorting algorithms may require additional memory.

Better Approach

The complete range 0 to n has a known total sum:

n * (n + 1) / 2

Since nums contains every value from that range except one, subtracting the actual array sum from the expected sum directly gives the missing number.

This removes the need for sorting and reduces the time complexity to linear time.

Algorithm

  • Store the size of nums in n, because the complete expected range is 0 through n.

  • Compute the expected sum of this range using n * (n + 1) / 2.

  • Initialize actualSum = 0 to accumulate the values present in the array.

  • Traverse nums and add every element to actualSum.

  • Return expectedSum - actualSum, because the difference is the only value absent from the array.

Dry Run

Missing Number Better Approach Dry Run .png

Missing Number Better Approach Dry Run .png

Solution

#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
int missingNumber(vector<int>& nums) {
long long n = nums.size();
/*
* Use a wider integer type because n * (n + 1)
* may exceed the range of a regular int.
*/
long long expectedSum = n * (n + 1) / 2;
long long actualSum = 0;
for (int value : nums) {
actualSum += value;
}
/*
* Every expected value except the missing one
* appears in actualSum, so the difference is the answer.
*/
return static_cast<int>(expectedSum - actualSum);
}
};
int main() {
vector<int> nums = {3, 0, 1};
Solution solution;
cout << solution.missingNumber(nums) << endl;
return 0;
}

Complexity Analysis

Time Complexity: O(N), because the array is traversed once.

Space Complexity: O(1), because only a few variables are used.

Optimal Approach

XOR is useful because identical values cancel each other:

x ^ x = 0

and:

x ^ 0 = x

XOR all numbers from 0 to n and also XOR every value present in nums. Every number that appears in both groups cancels out, leaving only the missing value.

Unlike the summation method, this approach does not build a potentially large arithmetic total, so it avoids intermediate sum overflow concerns.

Algorithm

  • Initialize xorExpected = 0 and xorActual = 0 to separately track the XOR of the expected range and the array values.

  • Traverse the array indices from 0 to n - 1.

  • XOR each index i into xorExpected, because these indices represent values from the expected range.

  • XOR nums[i] into xorActual to accumulate all values actually present in the array.

  • XOR n into xorExpected after the loop, because the expected range contains one additional value n.

  • Return xorExpected ^ xorActual. Every common value cancels, leaving only the missing number.

Dry Run

Missing Number Optimal Approach Dry Run .png

Missing Number Optimal Approach Dry Run .png

Solution

#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
int missingNumber(vector<int>& nums) {
int n = nums.size();
/*
* xorExpected tracks values from the complete range,
* while xorActual tracks values present in the array.
*/
int xorExpected = 0;
int xorActual = 0;
for (int i = 0; i < n; i++) {
xorExpected ^= i;
xorActual ^= nums[i];
}
/*
* Indices cover only 0 to n - 1, so include n
* separately to complete the expected range.
*/
xorExpected ^= n;
/*
* Values present in both groups cancel because x ^ x = 0,
* leaving only the number missing from nums.
*/
return xorExpected ^ xorActual;
}
};
int main() {
vector<int> nums = {3, 0, 1};
Solution solution;
cout << solution.missingNumber(nums) << endl;
return 0;
}

Complexity Analysis

Time Complexity: O(N), because the array is traversed once and each XOR operation takes constant time.

Space Complexity: O(1), because only a few integer variables are used.

Interview follow-up Questions

If nums[i] = i for every index from 0 to n - 1, then every value in that range is present. The only remaining value from the complete range 0 to n is n.

Bit Manipulation

Read Similar Blogs

Comments0