2965. Find Missing and Repeated Values
Problem Description
You are given a 2D integer matrix grid
with dimensions n × n
(0-indexed). The matrix contains values ranging from 1 to n²
.
The matrix has the following properties:
- Every integer from 1 to
n²
should appear exactly once - However, there's one integer
a
that appears twice (duplicate) - And there's one integer
b
that is missing (doesn't appear at all)
Your task is to identify these two numbers:
- Find the number
a
that appears twice in the matrix - Find the number
b
that is missing from the matrix
Return your answer as an array ans
of size 2, where:
ans[0]
=a
(the repeated number)ans[1]
=b
(the missing number)
For example, if you have a 2×2 matrix that should contain numbers 1 through 4, but instead contains [1, 2, 2, 3], then:
- The number 2 appears twice (repeated)
- The number 4 is missing
- You would return [2, 4]
Intuition
The key insight is that we need to track which numbers appear in the matrix and how many times each appears. Since we know the matrix should contain exactly the numbers from 1 to n²
, we can use a frequency counting approach.
Think of it like taking attendance in a classroom where each student has a unique ID from 1 to n²
. We go through the entire matrix and mark how many times we see each number. After counting:
- The number that was marked twice is our duplicate
- The number that was never marked is our missing value
Why does counting work here? Because we have a well-defined range [1, n²]
and we know exactly what should be present. It's like having a checklist of numbers 1 through n²
and checking off each number as we encounter it in the matrix.
The counting array cnt
acts as our checklist where cnt[i]
tells us how many times number i
appears in the matrix. In a perfect scenario, every cnt[i]
would be 1. But since we have one duplicate and one missing:
- One position will have
cnt[i] = 2
(the repeated number) - One position will have
cnt[i] = 0
(the missing number) - All other positions will have
cnt[i] = 1
This approach is straightforward because we're directly addressing what the problem asks for - finding frequencies of numbers in a known range.
Learn more about Math patterns.
Solution Approach
The implementation follows a counting strategy using an array to track the frequency of each number:
Step 1: Initialize the Counting Array
We create an array cnt
of size n * n + 1
initialized with zeros. We use size n * n + 1
instead of n * n
to make indexing convenient - cnt[i]
will store the count of number i
, and we can ignore index 0.
n = len(grid)
cnt = [0] * (n * n + 1)
Step 2: Count Frequencies
We traverse through the entire matrix and increment the count for each number we encounter:
for row in grid: for v in row: cnt[v] += 1
After this step:
cnt[i] = 0
means numberi
never appeared (missing)cnt[i] = 1
means numberi
appeared exactly once (normal)cnt[i] = 2
means numberi
appeared twice (duplicate)
Step 3: Find the Duplicate and Missing Numbers
We iterate through numbers 1 to n²
and check their frequencies:
ans = [0] * 2
for i in range(1, n * n + 1):
if cnt[i] == 2:
ans[0] = i # Found the duplicate
if cnt[i] == 0:
ans[1] = i # Found the missing number
Time and Space Complexity:
- Time Complexity:
O(n²)
for traversing the matrix once and then checking the count array once - Space Complexity:
O(n²)
for the counting array
The beauty of this solution lies in its simplicity - we're essentially creating a frequency map and then scanning it to find anomalies (count of 2 for duplicate, count of 0 for missing).
Ready to land your dream job?
Unlock your dream job with a 5-minute evaluator for a personalized learning plan!
Start EvaluatorExample Walkthrough
Let's walk through a concrete example with a 3×3 matrix that should contain numbers 1 through 9.
Given matrix:
grid = [[1, 3, 2], [9, 7, 6], [5, 3, 8]]
Step 1: Initialize the counting array
We create cnt
with size 10 (n² + 1 = 9 + 1):
cnt = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] index: 0 1 2 3 4 5 6 7 8 9
Step 2: Count frequencies by traversing the matrix
Processing row by row:
-
Row 1: [1, 3, 2]
- See 1:
cnt[1]++
→ cnt = [0, 1, 0, 0, 0, 0, 0, 0, 0, 0] - See 3:
cnt[3]++
→ cnt = [0, 1, 0, 1, 0, 0, 0, 0, 0, 0] - See 2:
cnt[2]++
→ cnt = [0, 1, 1, 1, 0, 0, 0, 0, 0, 0]
- See 1:
-
Row 2: [9, 7, 6]
- See 9:
cnt[9]++
→ cnt = [0, 1, 1, 1, 0, 0, 0, 0, 0, 1] - See 7:
cnt[7]++
→ cnt = [0, 1, 1, 1, 0, 0, 0, 1, 0, 1] - See 6:
cnt[6]++
→ cnt = [0, 1, 1, 1, 0, 0, 1, 1, 0, 1]
- See 9:
-
Row 3: [5, 3, 8]
- See 5:
cnt[5]++
→ cnt = [0, 1, 1, 1, 0, 1, 1, 1, 0, 1] - See 3:
cnt[3]++
→ cnt = [0, 1, 1, 2, 0, 1, 1, 1, 0, 1] - See 8:
cnt[8]++
→ cnt = [0, 1, 1, 2, 0, 1, 1, 1, 1, 1]
- See 5:
Final count array:
cnt = [0, 1, 1, 2, 0, 1, 1, 1, 1, 1] index: 0 1 2 3 4 5 6 7 8 9
Step 3: Find the duplicate and missing numbers
Scan through indices 1 to 9:
- i = 1: cnt[1] = 1 (normal)
- i = 2: cnt[2] = 1 (normal)
- i = 3: cnt[3] = 2 ✓ Found duplicate! ans[0] = 3
- i = 4: cnt[4] = 0 ✓ Found missing! ans[1] = 4
- i = 5: cnt[5] = 1 (normal)
- i = 6: cnt[6] = 1 (normal)
- i = 7: cnt[7] = 1 (normal)
- i = 8: cnt[8] = 1 (normal)
- i = 9: cnt[9] = 1 (normal)
Result: ans = [3, 4]
- The number 3 appears twice in the matrix
- The number 4 is missing from the matrix
Solution Implementation
1class Solution:
2 def findMissingAndRepeatedValues(self, grid: List[List[int]]) -> List[int]:
3 """
4 Find the repeated and missing values in an n×n grid.
5
6 Args:
7 grid: A 2D list containing values from 1 to n²
8
9 Returns:
10 A list of two integers [repeated_value, missing_value]
11 """
12 # Get the dimension of the square grid
13 n = len(grid)
14
15 # Initialize frequency counter for values 1 to n²
16 # Index 0 is unused, indices 1 to n² track occurrences
17 frequency_count = [0] * (n * n + 1)
18
19 # Count occurrences of each value in the grid
20 for row in grid:
21 for value in row:
22 frequency_count[value] += 1
23
24 # Initialize result array to store [repeated, missing] values
25 result = [0, 0]
26
27 # Iterate through all expected values (1 to n²)
28 for i in range(1, n * n + 1):
29 # Check if value appears twice (repeated)
30 if frequency_count[i] == 2:
31 result[0] = i
32 # Check if value never appears (missing)
33 if frequency_count[i] == 0:
34 result[1] = i
35
36 return result
37
1class Solution {
2 public int[] findMissingAndRepeatedValues(int[][] grid) {
3 // Get the size of the grid (n x n)
4 int n = grid.length;
5
6 // Create a frequency array to count occurrences of each number
7 // Size is n*n + 1 to accommodate values from 1 to n*n
8 int[] frequency = new int[n * n + 1];
9
10 // Initialize result array to store [repeated value, missing value]
11 int[] result = new int[2];
12
13 // Iterate through each row in the grid
14 for (int[] row : grid) {
15 // Iterate through each element in the current row
16 for (int value : row) {
17 // Increment the frequency count for the current value
18 // If the count becomes 2, this is the repeated value
19 if (++frequency[value] == 2) {
20 result[0] = value;
21 }
22 }
23 }
24
25 // Find the missing value by checking which number has frequency 0
26 for (int i = 1; ; ++i) {
27 // If frequency is 0, this number is missing from the grid
28 if (frequency[i] == 0) {
29 result[1] = i;
30 return result;
31 }
32 }
33 }
34}
35
1class Solution {
2public:
3 vector<int> findMissingAndRepeatedValues(vector<vector<int>>& grid) {
4 int n = grid.size();
5
6 // Create frequency array to count occurrences of each number from 1 to n*n
7 // Index 0 is unused since valid numbers start from 1
8 vector<int> frequency(n * n + 1, 0);
9
10 // Result array: [repeated_value, missing_value]
11 vector<int> result(2);
12
13 // Traverse the 2D grid and count frequency of each number
14 for (const auto& row : grid) {
15 for (int value : row) {
16 frequency[value]++;
17
18 // If a number appears twice, it's the repeated value
19 if (frequency[value] == 2) {
20 result[0] = value;
21 }
22 }
23 }
24
25 // Find the missing number by checking which number has frequency 0
26 for (int number = 1; number <= n * n; number++) {
27 if (frequency[number] == 0) {
28 result[1] = number;
29 return result;
30 }
31 }
32
33 // This line should never be reached given valid input
34 return result;
35 }
36};
37
1/**
2 * Finds the missing and repeated values in a 2D grid.
3 * The grid should contain all numbers from 1 to n*n, where one number appears twice and one is missing.
4 *
5 * @param grid - A 2D array of numbers
6 * @returns An array where the first element is the repeated value and the second is the missing value
7 */
8function findMissingAndRepeatedValues(grid: number[][]): number[] {
9 // Get the dimension of the grid
10 const gridSize: number = grid.length;
11
12 // Initialize frequency counter array for numbers 1 to n*n
13 // Index 0 is unused since valid numbers start from 1
14 const frequencyCounter: number[] = Array(gridSize * gridSize + 1).fill(0);
15
16 // Initialize result array: [repeated value, missing value]
17 const result: number[] = Array(2).fill(0);
18
19 // Count the frequency of each number in the grid
20 for (const row of grid) {
21 for (const value of row) {
22 // Increment frequency and check if this number appears twice
23 frequencyCounter[value]++;
24 if (frequencyCounter[value] === 2) {
25 // Found the repeated value
26 result[0] = value;
27 }
28 }
29 }
30
31 // Find the missing value by checking which number has frequency 0
32 for (let number = 1; ; number++) {
33 if (frequencyCounter[number] === 0) {
34 // Found the missing value
35 result[1] = number;
36 return result;
37 }
38 }
39}
40
Time and Space Complexity
The time complexity is O(n²)
, where n
is the side length of the matrix. This is because:
- The nested loops iterate through all elements in the
n × n
grid, performingn²
iterations - Each operation inside the loops (accessing and incrementing
cnt[v]
) takesO(1)
time - The second loop iterates from 1 to
n²
, which is alsoO(n²)
iterations - Overall:
O(n²) + O(n²) = O(n²)
The space complexity is O(n²)
, where n
is the side length of the matrix. This is because:
- The
cnt
array has sizen² + 1
, which requiresO(n²)
space - The
ans
array has fixed size 2, which isO(1)
- Overall:
O(n²) + O(1) = O(n²)
Learn more about how to find time and space complexity quickly.
Common Pitfalls
1. Off-by-One Error in Array Sizing
A frequent mistake is creating the counting array with size n * n
instead of n * n + 1
:
Incorrect:
cnt = [0] * (n * n) # Wrong! This creates indices 0 to n²-1
Why it fails: Since we need to track numbers from 1 to n², we need indices 1 through n². With size n * n
, the array only has indices 0 to n²-1, causing an IndexError when trying to access cnt[n²]
.
Correct Solution:
cnt = [0] * (n * n + 1) # Correct! Indices 0 to n²
2. Early Termination Optimization Trap
Some might try to optimize by breaking early once both values are found:
Problematic:
for i in range(1, n * n + 1):
if cnt[i] == 2:
ans[0] = i
if cnt[i] == 0:
ans[1] = i
if ans[0] != 0 and ans[1] != 0:
break # Seems logical but can cause issues
Why it's risky: While this works in theory, it assumes both conditions will be met before the loop ends. If there's any edge case or data corruption where multiple duplicates exist (even though the problem guarantees exactly one), this could return incorrect partial results.
Better Approach: Keep the simple iteration without early breaks - the performance gain is negligible for this problem size, and the code remains more robust.
3. Using a Dictionary Instead of Array
While using a dictionary seems intuitive for frequency counting:
Alternative approach:
freq = {} for row in grid: for v in row: freq[v] = freq.get(v, 0) + 1
The issue: You then need to check for missing values differently:
for i in range(1, n * n + 1):
if i not in freq: # Missing value
ans[1] = i
elif freq[i] == 2: # Duplicate
ans[0] = i
While this works, it's slightly less efficient due to dictionary operations and the need to explicitly check for missing keys. The array approach is cleaner since missing values naturally have a count of 0.
Which algorithm is best for finding the shortest distance between two points in an unweighted graph?
Recommended Readings
Math for Technical Interviews How much math do I need to know for technical interviews The short answer is about high school level math Computer science is often associated with math and some universities even place their computer science department under the math faculty However the reality is that you
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 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
Want a Structured Path to Master System Design Too? Don’t Miss This!