3718. Smallest Missing Multiple of K
Problem Description
You are given an integer array nums and an integer k. Your task is to find the smallest positive multiple of k that does not appear in nums.
A multiple of k is any positive integer that is divisible by k. In other words, the multiples of k are k * 1, k * 2, k * 3, and so on.
For example, if nums = [2, 4, 8] and k = 2:
- The multiples of
2in order are:2,4,6,8, ... 2is in the array,4is in the array, but6is not.- Therefore, the answer is
6.
The goal is to check the multiples of k one by one, starting from the smallest (k * 1), and return the first one that is missing from the array.
How We Pick the Algorithm
Why Hash Table / Counting?
This problem maps to Hash Table / Counting through a short path in the full flowchart.
Building a hash set for O(1) membership queries lets us check each multiple of k sequentially until finding a missing one.
Open in FlowchartIntuition
The problem asks for the smallest missing positive multiple of k, which naturally suggests a simple strategy: check the multiples of k one by one in increasing order — k * 1, k * 2, k * 3, ... — and stop as soon as we find one that is not in nums. Since we check them from smallest to largest, the first missing one we encounter is guaranteed to be the answer.
The only remaining concern is efficiency. For each multiple, we need to ask: "does this value exist in nums?" If we scan the entire array every time, each check costs O(n). Instead, we can put all elements of nums into a hash set first. A hash set answers membership queries in O(1) on average, so every check becomes instant.
We also know this process must terminate quickly. The array has only n elements, so it can contain at most n distinct multiples of k. That means by the time we reach the multiple k * (n + 1), at least one of the first n + 1 multiples must be missing. Therefore, the enumeration runs at most n + 1 rounds, giving an overall linear-time solution.
Solution Approach
We use a hash table (set) combined with enumeration, following these steps:
Step 1: Build a hash set from the array
We first store all the numbers from nums into a set s:
s = set(nums)
This is the key data structure choice. Converting the array into a set takes O(n) time once, and afterwards each membership check x in s runs in O(1) on average — far better than scanning the array repeatedly.
Step 2: Enumerate multiples of k in increasing order
Starting from i = 1, we generate each positive multiple x = k * i in sequence:
for i in count(1): x = k * i
Here count(1) from the itertools module produces the infinite sequence 1, 2, 3, ..., so x takes the values k, 2k, 3k, ... in order.
Step 3: Return the first missing multiple
For each multiple x, we check whether it exists in the set. The moment we find one that is absent, we return it immediately:
if x not in s: return x
Because we enumerate multiples from smallest to largest, the first absent multiple is guaranteed to be the smallest missing one — exactly what the problem asks for.
Complete Code
class Solution:
def missingMultiple(self, nums: List[int], k: int) -> int:
s = set(nums)
for i in count(1):
x = k * i
if x not in s:
return x
Complexity Analysis
- Time Complexity:
O(n), wherenis the length ofnums. Building the set costsO(n). Sincenumscontains at mostndistinct multiples ofk, the loop runs at mostn + 1iterations, each with anO(1)set lookup. - Space Complexity:
O(n), used by the hash set storing the elements ofnums.
Example Walkthrough
Let's trace through the solution with nums = [3, 9, 6, 10] and k = 3.
Step 1: Build the hash set
Convert the array into a set for fast lookups:
s = {3, 9, 6, 10}
This one-time O(n) step lets every subsequent membership check run in O(1).
Step 2 & 3: Enumerate multiples of k and check each one
We generate multiples of 3 in increasing order and test each against the set:
i | x = k * i | Is x in s? | Action |
|---|---|---|---|
| 1 | 3 | Yes (3 ∈ s) | Continue |
| 2 | 6 | Yes (6 ∈ s) | Continue |
| 3 | 9 | Yes (9 ∈ s) | Continue |
| 4 | 12 | No | Return 12 |
The multiples 3, 6, and 9 all appear in the array, so the loop keeps going. When we reach 12, the set lookup fails — this is the first multiple of 3 missing from nums.
Result: 12
Notice two key properties confirmed by this trace:
- Correctness — since multiples are checked from smallest to largest, the first absent one (
12) is guaranteed to be the smallest missing multiple. Note that10being in the array is irrelevant; it isn't a multiple of3, so it never affects the enumeration. - Bounded iterations — the array has
n = 4elements, so at most4distinct multiples of3can appear in it. The loop is therefore guaranteed to terminate withinn + 1 = 5iterations; here it stopped at the 4th.
Solution Implementation
1from typing import List
2from itertools import count
3
4
5class Solution:
6 def missingMultiple(self, nums: List[int], k: int) -> int:
7 # Store all numbers in a hash set for O(1) membership checks
8 num_set = set(nums)
9
10 # Enumerate positive multiples of k: k * 1, k * 2, k * 3, ...
11 for multiplier in count(1):
12 multiple = k * multiplier
13 # The first multiple of k not present in the set is the answer
14 if multiple not in num_set:
15 return multiple
161class Solution {
2 public int missingMultiple(int[] nums, int k) {
3 // Use a boolean array as a presence set for values in nums.
4 // Values are assumed to be in the range [0, 100].
5 boolean[] present = new boolean[101];
6
7 // Mark each number in nums as present.
8 for (int num : nums) {
9 present[num] = true;
10 }
11
12 // Check multiples of k in increasing order: k, 2k, 3k, ...
13 for (int i = 1;; ++i) {
14 int multiple = k * i;
15
16 // Return the first multiple that is either out of the array's
17 // range (and therefore cannot appear in nums) or not present.
18 if (multiple >= present.length || !present[multiple]) {
19 return multiple;
20 }
21 }
22 }
23}
24```
25
26**Explanation of the approach:**
27
281. **Presence tracking:** A `boolean` array `present` of size 101 acts as a lightweight hash set, marking which values from `nums` exist. This works because the values are bounded by 100.
29
302. **Iterating multiples:** Starting from `i = 1`, each multiple `k * i` is computed in ascending order, guaranteeing the *smallest* missing multiple is found first.
31
323. **Termination condition:** The loop returns when a multiple either exceeds the array bounds (meaning it can't possibly be in `nums`) or is simply absent from the set. This ensures the loop always terminates.
33
34**Alternative perspective:** A `HashSet<Integer>` could replace the boolean array if the value range were unbounded, trading constant-factor speed for flexibility:
35
36```java
37Set<Integer> seen = new HashSet<>();
38for (int num : nums) seen.add(num);
39for (int i = 1;; ++i) {
40 if (!seen.contains(k * i)) return k * i;
41}
421class Solution {
2public:
3 int missingMultiple(vector<int>& nums, int k) {
4 // Store all elements of nums in a hash set for O(1) lookups
5 unordered_set<int> numSet(nums.begin(), nums.end());
6
7 // Check multiples of k in increasing order: k, 2k, 3k, ...
8 for (int i = 1;; ++i) {
9 int multiple = k * i;
10 // The first multiple of k not present in the set is the answer
11 if (!numSet.contains(multiple)) {
12 return multiple;
13 }
14 }
15 }
16};
171/**
2 * Finds the smallest positive multiple of k that is missing from the given array.
3 *
4 * @param nums - The array of numbers to search within.
5 * @param k - The base number whose multiples are checked.
6 * @returns The smallest positive multiple of k not present in nums.
7 */
8function missingMultiple(nums: number[], k: number): number {
9 // Store all elements of nums in a Set for O(1) lookups
10 const numSet = new Set<number>(nums);
11
12 // Iterate over positive integers, checking each multiple of k
13 for (let i = 1; ; ++i) {
14 // Compute the i-th multiple of k
15 const multiple = k * i;
16
17 // If this multiple is not in the set, it is the smallest missing one
18 if (!numSet.has(multiple)) {
19 return multiple;
20 }
21 }
22}
23Time and Space Complexity
-
Time complexity:
O(n), wherenis the length of the arraynums.- Building the set
s = set(nums)takesO(n)time. - The loop iterates over multiples of
k(i.e.,k * 1,k * 2, ...). Since the setscontains at mostnelements, among the firstn + 1multiples ofk, at least one must be missing froms. Therefore, the loop runs at mostn + 1times, and each membership checkx not in stakesO(1)on average. - Overall:
O(n) + O(n) = O(n).
- Building the set
-
Space complexity:
O(n), wherenis the length of the arraynums.- The set
sstores up tonelements fromnums, requiringO(n)extra space. - All other variables (
i,x) use onlyO(1)space.
- The set
Pattern Learn more about how to find time and space complexity quickly.
Common Pitfalls
Pitfall 1: Checking membership against the list instead of a set
A very common mistake is to skip the set conversion and write the check directly on the array:
class Solution:
def missingMultiple(self, nums: List[int], k: int) -> int:
for i in count(1):
x = k * i
if x not in nums: # ❌ O(n) lookup on a list!
return x
Why it's wrong (or at least bad): The result is still correct, but x not in nums performs a linear scan of the list every iteration. Since the loop can run up to n + 1 times, the overall time complexity degrades from O(n) to O(n²), which can time out on large inputs.
Solution: Always convert nums to a set first (s = set(nums)) so each membership test is O(1) on average.
Pitfall 2: Starting the enumeration from 0 instead of 1
for i in count(0): # ❌ starts at i = 0 x = k * i # first candidate is 0 if x not in s: return x
Why it's wrong: k * 0 = 0 is not a positive multiple of k. If 0 happens to be absent from nums (which is typical), this code immediately returns 0, which is invalid. The problem explicitly defines multiples as starting from k * 1.
Solution: Begin the counter at 1 — count(1) or while True with i = 1 — so the first candidate is k itself.
Pitfall 3: Inverting the logic — scanning nums for multiples instead of enumerating multiples
Some attempts iterate over the array, collect multiples of k, and then try to "find the gap" by sorting:
multiples = sorted(x for x in nums if x % k == 0)
expected = k
for m in multiples:
if m == expected:
expected += k
return expected # ❌ breaks when nums contains duplicates
Why it's wrong: Duplicates derail the matching. For nums = [2, 2, 4] and k = 2, the sorted multiples are [2, 2, 4]; the second 2 fails to match expected = 4, the pointer never advances past it correctly unless extra duplicate handling is added, and the code may return a wrong answer. It also adds an unnecessary O(n log n) sort.
Solution: Deduplicate via a set and enumerate candidates k, 2k, 3k, ... directly, as in the reference solution. This sidesteps duplicates and sorting entirely.
Pitfall 4: Worrying about (or causing) an unbounded loop
At first glance, for i in count(1) looks like it could run forever, and some defensive rewrites cap it incorrectly:
for i in range(1, len(nums)): # ❌ off-by-one: loop bound is too small
...
Why it's wrong: The array contains at most n distinct multiples of k, so by the pigeonhole principle the answer is found within the first n + 1 multiples — the infinite iterator is guaranteed to terminate. But if you replace it with a bounded loop, the bound must cover n + 1 candidates. range(1, len(nums)) only checks n - 1 multiples and can fall off the end without returning (e.g., nums = [2, 4], k = 2 → never tests 6).
Solution: Either trust count(1) (termination is provable), or use range(1, len(nums) + 2) so all n + 1 necessary candidates are covered.
Ready to land your dream job?
Unlock your dream job with a 5-minute quiz for a personalized study roadmap!
Get My RoadmapConsider the classic dynamic programming of fibonacci numbers, what is the recurrence relation?
Recommended Readings
Coding Interview Patterns Your Personal Dijkstra's Algorithm to Landing Your Dream Job The goal of AlgoMonster is to help you get a job in the shortest amount of time possible in a data driven way We compiled datasets of tech interview problems and broke them down by patterns This way
Recursion If you prefer videos here's a video that explains recursion in a fun and easy way Recursion is one of the most important concepts in computer science Simply speaking recursion is the process of a function calling itself Using a real life analogy imagine a scenario where you invite your friends to lunch https assets algo monster recursion jpg You first call Ben and ask him
Runtime Overview When learning about algorithms and data structures you'll frequently encounter the term time complexity This concept is fundamental in computer science and offers insights into how long an algorithm takes to complete given a certain input size What is Time Complexity Time complexity describes how the time needed
Want a Structured Path to Master System Design Too? Don’t Miss This!