Want Help Cracking FAANG?

(Then click this)

×
Back to Question Bank

1613. Find the Missing IDs - Leetcode Solution

Problem Description

You are given an array of integers ids that contains unique IDs from 1 to n, but some IDs are missing. The array may not be sorted. Your task is to find all the missing IDs in the range from 1 to n that are not present in ids. Return the missing IDs in a sorted list.

  • Input: An array ids of length m (where m <= n) and an integer n.
  • Output: A list of integers containing all missing IDs in the range 1 to n (inclusive), sorted in ascending order.
  • Each ID is a unique integer between 1 and n.
  • Do not reuse elements and do not mutate the input array.
  • There is at least one missing ID, and there may be multiple missing IDs.

Thought Process

The problem is to identify which IDs from 1 to n are missing from the given ids array. A brute-force approach would be to check, for each number from 1 to n, whether it exists in ids. However, this would be inefficient, especially for large values of n and m, since searching in an array takes O(m) time for each check.

To optimize, we need a way to quickly check if a number is present in ids. Using a set data structure allows O(1) lookups, making it much more efficient. Thus, the plan is to convert ids to a set, and then iterate from 1 to n, collecting numbers not found in the set.

This approach is both simple and fast, leveraging the properties of sets for quick membership tests.

Solution Approach

  • Step 1: Convert the input array ids into a set. This allows for O(1) lookup times when checking if an ID is present.
  • Step 2: Initialize an empty list to store missing IDs.
  • Step 3: Iterate through numbers from 1 to n (inclusive).
  • Step 4: For each number, check if it is not in the set of ids. If it is not, add it to the list of missing IDs.
  • Step 5: Return the list of missing IDs. Since we iterate from 1 to n, the list is naturally sorted in ascending order.

This method is efficient and straightforward, making use of built-in data structures to minimize code complexity and maximize performance.

Example Walkthrough

Sample Input:
ids = [4, 3, 2, 7, 8, 2, 3, 1]
n = 8

  1. Convert ids to a set: {1, 2, 3, 4, 7, 8} (duplicates are removed automatically).
  2. Iterate from 1 to 8:
    • 1: Present in set? Yes. Skip.
    • 2: Present in set? Yes. Skip.
    • 3: Present in set? Yes. Skip.
    • 4: Present in set? Yes. Skip.
    • 5: Present in set? No. Add to missing list.
    • 6: Present in set? No. Add to missing list.
    • 7: Present in set? Yes. Skip.
    • 8: Present in set? Yes. Skip.
  3. Result: [5, 6]

The missing IDs in the range 1 to 8 are 5 and 6.

Time and Space Complexity

  • Brute-force approach:
    • For each number from 1 to n, check if it is in ids (O(m) per check).
    • Total time: O(n * m).
    • Space: O(1) extra (if not counting the output).
  • Optimized approach (using a set):
    • Convert ids to a set: O(m) time and O(m) space.
    • Iterate from 1 to n, checking set membership: O(n) time.
    • Total time: O(m + n).
    • Total space: O(m) for the set, plus O(k) for the output list (where k is the number of missing IDs).

The optimized approach is much faster and uses reasonable extra space for practical input sizes.

Summary

To find missing IDs from a range given a list of present IDs, the most efficient method is to use a set for constant-time lookups. This allows us to check each number in the range quickly and collect any that are missing. The approach is simple, leverages built-in data structures, and is easy to implement in any programming language. The key insight is to reduce repeated searches by converting the input to a set, resulting in a clean and efficient solution.

Code Implementation

def find_missing_ids(ids, n):
    present = set(ids)
    missing = []
    for i in range(1, n + 1):
        if i not in present:
            missing.append(i)
    return missing
      
#include <vector>
#include <unordered_set>

std::vector<int> findMissingIDs(const std::vector<int>& ids, int n) {
    std::unordered_set<int> present(ids.begin(), ids.end());
    std::vector<int> missing;
    for (int i = 1; i <= n; ++i) {
        if (present.find(i) == present.end()) {
            missing.push_back(i);
        }
    }
    return missing;
}
      
import java.util.*;

public class Solution {
    public List<Integer> findMissingIDs(int[] ids, int n) {
        Set<Integer> present = new HashSet<>();
        for (int id : ids) {
            present.add(id);
        }
        List<Integer> missing = new ArrayList<>();
        for (int i = 1; i <= n; i++) {
            if (!present.contains(i)) {
                missing.add(i);
            }
        }
        return missing;
    }
}
      
function findMissingIDs(ids, n) {
    const present = new Set(ids);
    const missing = [];
    for (let i = 1; i <= n; i++) {
        if (!present.has(i)) {
            missing.push(i);
        }
    }
    return missing;
}