2028. Find Missing Observations
Problem Description
You are given information about dice rolls where some observations are missing. Here's the scenario:
- You originally had
n + m
dice rolls (using standard 6-sided dice with faces numbered 1 to 6) - You lost the records of
n
rolls and only havem
rolls remaining - You know the average value of all
n + m
rolls
Given:
- An array
rolls
of lengthm
containing the values of the known dice rolls - An integer
mean
representing the average of alln + m
rolls - An integer
n
representing the number of missing rolls
Your task is to find the n
missing dice roll values such that when combined with the known m
rolls, the average equals exactly mean
.
Key constraints:
- Each die shows a value between 1 and 6 (inclusive)
- The average is calculated as the sum of all values divided by the total count
- Since
mean
is an integer, the total sum must be divisible byn + m
- If multiple valid answers exist, return any one of them
- If no valid answer exists, return an empty array
For example, if you have 3 known rolls [3, 2, 4]
with mean = 4
and n = 2
missing rolls, you need to find 2 values (each between 1-6) such that the average of all 5 rolls equals 4. This means the total sum should be 5 × 4 = 20
. Since the known rolls sum to 9, the missing rolls must sum to 11, which could be [5, 6]
or [6, 5]
.
Intuition
The key insight is to work backwards from the given average to find what the missing rolls must sum to.
Since we know the average of all n + m
rolls is mean
, we can calculate the total sum of all rolls: total_sum = (n + m) × mean
.
We already have m
rolls, so we can find their sum. The difference between the total sum and the known sum tells us exactly what the n
missing rolls must add up to: missing_sum = total_sum - sum(known_rolls)
.
Now we need to check if it's possible to create n
dice rolls that sum to missing_sum
. Each die can show values from 1 to 6, so:
- The minimum possible sum for
n
dice isn × 1 = n
- The maximum possible sum for
n
dice isn × 6
If missing_sum
falls outside the range [n, n × 6]
, it's impossible to achieve, so we return an empty array.
If it's possible, we need to distribute missing_sum
across n
dice. The simplest approach is to distribute as evenly as possible:
- Start by giving each die the value
missing_sum // n
(integer division) - This leaves a remainder of
missing_sum % n
- Distribute this remainder by adding 1 to the first
missing_sum % n
dice
This greedy distribution works because:
- We're guaranteed each die value stays within [1, 6] since we already checked the sum is achievable
- It's the most straightforward way to construct a valid answer
- Any valid distribution will work according to the problem statement
Learn more about Math patterns.
Solution Approach
The implementation follows the mathematical approach we identified:
-
Calculate the required sum for missing rolls:
- First, find the total sum needed:
total_sum = (n + m) × mean
- Calculate the sum of known rolls:
known_sum = sum(rolls)
- The missing rolls must sum to:
s = total_sum - known_sum
- First, find the total sum needed:
-
Check if a valid solution exists:
- Since each die shows values from 1 to 6, the sum
s
must satisfy:n ≤ s ≤ n × 6
- If
s < n
(less than minimum possible) ors > n × 6
(more than maximum possible), return an empty array
- Since each die shows values from 1 to 6, the sum
-
Construct the missing rolls using even distribution:
- Initialize all
n
missing rolls with the base value:s // n
- This uses up
n × (s // n)
from our required sum - We still need to distribute the remainder:
s % n
- Add 1 to the first
s % n
dice to distribute the remainder
- Initialize all
Here's how the algorithm works step by step:
m = len(rolls) # Get number of known rolls
s = (n + m) * mean - sum(rolls) # Calculate required sum for missing rolls
if s > n * 6 or s < n: # Check if solution is possible
return []
ans = [s // n] * n # Initialize all dice with base value
for i in range(s % n): # Distribute remainder
ans[i] += 1
return ans
This approach guarantees:
- All dice values remain within [1, 6] range
- The sum of missing rolls equals exactly
s
- The solution is constructed in
O(n)
time withO(n)
space
For example, if we need n = 3
missing rolls that sum to s = 11
:
- Base value:
11 // 3 = 3
, so start with[3, 3, 3]
- Remainder:
11 % 3 = 2
, so add 1 to first 2 elements - Final result:
[4, 4, 3]
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 to illustrate the solution approach.
Given:
- Known rolls:
rolls = [1, 5, 6]
(m = 3 rolls) - Mean of all rolls:
mean = 3
- Missing rolls:
n = 4
Step 1: Calculate the required sum for missing rolls
First, we need to find what the missing rolls must sum to:
- Total number of rolls:
n + m = 4 + 3 = 7
- Total sum needed:
total_sum = 7 × 3 = 21
- Sum of known rolls:
sum([1, 5, 6]) = 12
- Required sum for missing rolls:
s = 21 - 12 = 9
So our 4 missing dice must sum to exactly 9.
Step 2: Check if a valid solution exists
Can we create 4 dice rolls that sum to 9?
- Minimum possible sum:
4 × 1 = 4
(all dice show 1) - Maximum possible sum:
4 × 6 = 24
(all dice show 6) - Our required sum
s = 9
falls within the range [4, 24] ✓
Since 4 ≤ 9 ≤ 24, a valid solution exists!
Step 3: Construct the missing rolls
Now we distribute the sum of 9 across 4 dice:
- Base value for each die:
9 // 4 = 2
- Start with:
[2, 2, 2, 2]
(sum = 8) - Remainder to distribute:
9 % 4 = 1
- Add 1 to the first die:
[3, 2, 2, 2]
(sum = 9) ✓
Verification:
- All 7 rolls:
[1, 5, 6, 3, 2, 2, 2]
- Total sum:
1 + 5 + 6 + 3 + 2 + 2 + 2 = 21
- Average:
21 / 7 = 3
✓ - All dice values are between 1 and 6 ✓
The answer [3, 2, 2, 2]
satisfies all requirements!
Solution Implementation
1class Solution:
2 def missingRolls(self, rolls: List[int], mean: int, n: int) -> List[int]:
3 # Calculate the number of observed rolls
4 m = len(rolls)
5
6 # Calculate the required sum for the missing n rolls
7 # Total sum = (n + m) * mean, so missing sum = total sum - observed sum
8 missing_sum = (n + m) * mean - sum(rolls)
9
10 # Check if it's possible to achieve the missing sum with n dice rolls
11 # Each die shows 1-6, so minimum sum is n*1 and maximum sum is n*6
12 if missing_sum > n * 6 or missing_sum < n:
13 return []
14
15 # Initialize result array with base value (distribute sum evenly)
16 base_value = missing_sum // n
17 result = [base_value] * n
18
19 # Distribute the remainder by adding 1 to first (missing_sum % n) elements
20 remainder = missing_sum % n
21 for i in range(remainder):
22 result[i] += 1
23
24 return result
25
1class Solution {
2 public int[] missingRolls(int[] rolls, int mean, int n) {
3 // Calculate the number of observed rolls
4 int observedRollsCount = rolls.length;
5
6 // Calculate the total sum needed for all rolls (observed + missing)
7 int totalRequiredSum = (n + observedRollsCount) * mean;
8
9 // Subtract the sum of observed rolls to get the sum needed for missing rolls
10 for (int rollValue : rolls) {
11 totalRequiredSum -= rollValue;
12 }
13
14 // Check if the required sum for missing rolls is valid
15 // Each die roll must be between 1 and 6
16 if (totalRequiredSum > n * 6 || totalRequiredSum < n) {
17 return new int[0]; // Return empty array if impossible
18 }
19
20 // Create array for missing rolls
21 int[] missingRollsArray = new int[n];
22
23 // Distribute the sum evenly across all missing rolls (base value)
24 int baseValue = totalRequiredSum / n;
25 Arrays.fill(missingRollsArray, baseValue);
26
27 // Distribute the remainder by adding 1 to some rolls
28 int remainder = totalRequiredSum % n;
29 for (int i = 0; i < remainder; i++) {
30 missingRollsArray[i]++;
31 }
32
33 return missingRollsArray;
34 }
35}
36
1class Solution {
2public:
3 vector<int> missingRolls(vector<int>& rolls, int mean, int n) {
4 // Calculate the number of observed rolls
5 int observedRollsCount = rolls.size();
6
7 // Calculate the sum of observed rolls
8 int observedSum = accumulate(rolls.begin(), rolls.end(), 0);
9
10 // Calculate the total sum needed for all rolls (observed + missing)
11 int totalRequiredSum = (n + observedRollsCount) * mean;
12
13 // Calculate the sum needed for the missing rolls
14 int missingRollsSum = totalRequiredSum - observedSum;
15
16 // Check if it's possible to achieve the required sum with n dice rolls
17 // Each die shows values from 1 to 6
18 int minPossibleSum = n * 1; // All dice show 1
19 int maxPossibleSum = n * 6; // All dice show 6
20
21 if (missingRollsSum < minPossibleSum || missingRollsSum > maxPossibleSum) {
22 return {}; // Impossible to achieve the required sum
23 }
24
25 // Initialize all missing rolls with the base value (average)
26 int baseValue = missingRollsSum / n;
27 vector<int> missingRollsResult(n, baseValue);
28
29 // Distribute the remainder evenly by adding 1 to some dice
30 int remainder = missingRollsSum % n;
31 for (int i = 0; i < remainder; ++i) {
32 ++missingRollsResult[i];
33 }
34
35 return missingRollsResult;
36 }
37};
38
1/**
2 * Finds the missing dice rolls given existing rolls and target mean
3 * @param rolls - Array of existing dice roll values
4 * @param mean - Target mean value for all rolls (existing + missing)
5 * @param n - Number of missing rolls to find
6 * @returns Array of missing roll values, or empty array if impossible
7 */
8function missingRolls(rolls: number[], mean: number, n: number): number[] {
9 // Calculate the number of existing rolls
10 const existingRollsCount: number = rolls.length;
11
12 // Calculate the required sum for the missing rolls
13 // Total sum needed = (existing + missing rolls) * mean - sum of existing rolls
14 const existingRollsSum: number = rolls.reduce((accumulator: number, current: number) => accumulator + current, 0);
15 const requiredSumForMissingRolls: number = (n + existingRollsCount) * mean - existingRollsSum;
16
17 // Check if it's possible to achieve the required sum with n dice rolls
18 // Each die shows 1-6, so minimum sum is n*1 and maximum sum is n*6
19 if (requiredSumForMissingRolls > n * 6 || requiredSumForMissingRolls < n) {
20 return [];
21 }
22
23 // Distribute the required sum evenly across n dice
24 // Start by giving each die the floor value of the average
25 const baseValue: number = Math.floor(requiredSumForMissingRolls / n);
26 const result: number[] = Array(n).fill(baseValue);
27
28 // Distribute the remainder by adding 1 to some dice
29 const remainder: number = requiredSumForMissingRolls % n;
30 for (let i = 0; i < remainder; i++) {
31 result[i]++;
32 }
33
34 return result;
35}
36
Time and Space Complexity
Time Complexity: O(n + m)
The time complexity consists of:
O(m)
for calculatingsum(rolls)
wherem
is the length of the given rolls arrayO(n)
for creating the initial answer array with[s // n] * n
O(s % n)
for the loop that distributes the remainder, wheres % n < n
, so this isO(n)
in the worst case
Therefore, the overall time complexity is O(m) + O(n) + O(n) = O(n + m)
.
Space Complexity: O(1)
(excluding the output array)
The algorithm uses only a constant amount of extra space:
- Variables
m
,s
, and loop variablei
each requireO(1)
space - The answer array
ans
of sizen
is required for the output and is not counted in the space complexity analysis
If we were to include the output array, the space complexity would be O(n)
.
Learn more about how to find time and space complexity quickly.
Common Pitfalls
1. Integer Overflow in Sum Calculation
When calculating (n + m) * mean
, this multiplication can cause integer overflow for large values. In some languages like C++ or Java, this would result in incorrect calculations.
Problem Example:
# If n + m = 100000 and mean = 60000 # (n + m) * mean = 6,000,000,000 (exceeds 32-bit integer limit)
Solution:
- Use 64-bit integers or long data types in languages prone to overflow
- In Python, this isn't an issue due to arbitrary precision integers
- Alternative calculation order:
n * mean + m * mean
to reduce intermediate values
2. Incorrect Remainder Distribution
A common mistake is trying to distribute the remainder incorrectly, potentially creating invalid die values.
Problem Example:
# Wrong approach: result = [s // n] * n result[0] += s % n # Adding all remainder to one die - might exceed 6! # If s = 14, n = 3: base = 4, remainder = 2 # Wrong result: [6, 4, 4] ✓ (happens to work) # But if s = 17, n = 3: base = 5, remainder = 2 # Wrong result: [7, 5, 5] ✗ (7 is invalid!)
Solution: Distribute remainder by adding 1 to multiple dice:
for i in range(s % n):
result[i] += 1 # Add 1 to each of the first (s % n) dice
3. Forgetting Edge Case Validation
Not checking if the base value itself is valid (between 1 and 6).
Problem Example:
# If s = 21, n = 3: base = 7 (invalid even before remainder distribution) # If s = 2, n = 3: base = 0 (invalid, dice can't show 0)
Solution:
The validation if s > n * 6 or s < n:
handles this implicitly:
- If base value would be > 6, then
s > n * 6
- If base value would be < 1, then
s < n
4. Off-by-One Error in Validation
Using incorrect inequality operators in the validation check.
Problem Example:
# Wrong validation: if s >= n * 6 or s <= n: # Using >= and <= instead of > and < return [] # This would incorrectly reject valid cases: # s = 6, n = 1 (all 6s) would be rejected # s = 3, n = 3 (all 1s) would be rejected
Solution: Use strict inequalities for the impossible cases:
if s > n * 6 or s < n: # Correct validation return []
5. Not Handling Zero or Negative Missing Sum
Failing to handle cases where the known rolls already exceed or meet the required average.
Problem Example:
# rolls = [6, 6, 6], mean = 3, n = 2 # missing_sum = 5 * 3 - 18 = -3 (negative!)
Solution:
The validation if s < n:
catches this since negative numbers are less than any positive n.
Which of the two traversal algorithms (BFS and DFS) can be used to find whether two nodes are connected?
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!