3678. Smallest Absent Positive Greater Than Average
Problem Description
You are given an integer array nums.
Your task is to find the smallest positive integer that satisfies both of the following conditions:
- It is absent from
nums— meaning it does not appear anywhere in the array. - It is strictly greater than the average of all elements in
nums.
The average of the array is defined as the sum of all its elements divided by the number of elements, i.e., sum(nums) / len(nums). Note that the average can be a fractional value, and it can also be negative or zero if the array contains negative numbers.
Return that smallest absent positive integer.
Example
Suppose nums = [3, 5]:
- The average is
(3 + 5) / 2 = 4. - We need a positive integer strictly greater than
4that is not in the array. 5is greater than4, but it appears innums, so it is skipped.6is greater than4and absent fromnums, so the answer is6.
Suppose nums = [-1, -2, -3]:
- The average is
-2. - Any positive integer is already strictly greater than
-2. - The smallest positive integer is
1, and since1does not appear innums, the answer is1.
Key Points
- The answer must always be a positive integer (at least
1), even if the average is negative. - The answer must be strictly greater than the average — being equal to it is not enough.
- The answer must not exist in 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.
Store all elements in a hash set for O(1) membership checks, then scan upward from floor(average) + 1 until finding a value not present in the set.
Open in FlowchartIntuition
The problem gives us two constraints on the answer: it must be strictly greater than the average, and it must be absent from the array. The natural idea is to first figure out the smallest possible candidate, then move upward until we find a valid one.
Let's think about where to start searching:
- The answer must be a positive integer, so it is at least
1. - The answer must be strictly greater than the average
avg. The smallest integer strictly greater thanavgis⌊avg⌋ + 1. This works for both fractional averages (e.g.,avg = 3.5gives4) and exact integer averages (e.g.,avg = 4gives5, since equality is not allowed).
Combining both conditions, the smallest candidate worth checking is max(1, ⌊avg⌋ + 1). Anything smaller is guaranteed to violate at least one of the two conditions, so there is no reason to look below this value.
Now we only need to handle the "absent" condition. Starting from this candidate, we check whether it exists in the array. If it does, we try the next integer, and so on. Since checking membership in a list is O(n) per query, we put all elements into a hash set first, which makes each lookup O(1).
One more observation guarantees this loop terminates quickly: the array has only n elements, so at most n consecutive candidates can be blocked. Within at most n + 1 steps starting from max(1, ⌊avg⌋ + 1), we are certain to hit a number that is absent from the array. This bounds the total work at O(n) and confirms that a simple linear scan upward is efficient enough — no sorting or complex search is needed.
Solution Approach
We implement the idea in three clear steps, using a hash set as the core data structure.
Step 1: Build a hash set of the elements
s = set(nums)
We store all elements of nums in a set s. This allows us to check whether a candidate number exists in the array in O(1) average time, instead of scanning the whole list for every check.
Step 2: Compute the starting candidate
ans = max(1, sum(nums) // len(nums) + 1)
This single line combines both constraints into the smallest possible starting point:
sum(nums) // len(nums)is the floor of the average,⌊avg⌋. In Python, the//operator performs floor division, which rounds toward negative infinity, so this works correctly even when the sum is negative (e.g.,-5 // 2 = -3).- Adding
1gives⌊avg⌋ + 1, the smallest integer strictly greater than the average. This holds in both cases:- If
avgis fractional (say3.5), then⌊avg⌋ + 1 = 4 > 3.5. ✓ - If
avgis an exact integer (say4), then⌊avg⌋ + 1 = 5 > 4, correctly skipping4itself since equality is forbidden. ✓
- If
- Wrapping it in
max(1, ...)enforces the positive requirement: if the average is negative or zero, the candidate could drop below1, so we clamp it up to1.
Step 3: Scan upward until the candidate is absent
while ans in s: ans += 1 return ans
Starting from the candidate, we repeatedly check membership in the set. If the current value exists in nums, we move to the next integer. The loop is guaranteed to stop within at most n + 1 iterations, because the set contains only n elements and cannot block more than n consecutive integers.
Complete Code
class Solution:
def smallestAbsent(self, nums: List[int]) -> int:
s = set(nums)
ans = max(1, sum(nums) // len(nums) + 1)
while ans in s:
ans += 1
return ans
Complexity Analysis
Let n be the length of nums.
- Time complexity:
O(n)— building the set takesO(n), computing the sum takesO(n), and the while loop runs at mostn + 1times withO(1)lookups each. - Space complexity:
O(n)— the hash set stores up tondistinct elements.
Example Walkthrough
Let's trace through the solution with nums = [4, 5, 2, 6].
Step 1: Build the hash set
s = set(nums) # s = {2, 4, 5, 6}
All four elements go into the set, so each future membership check costs O(1).
Step 2: Compute the starting candidate
- Sum:
4 + 5 + 2 + 6 = 17 - Length:
4 - Floor of the average:
17 // 4 = 4(the true average is4.25) - Add one:
4 + 1 = 5— the smallest integer strictly greater than4.25 - Clamp to positive:
max(1, 5) = 5
So ans = 5. Nothing below 5 can be valid: 4 and below fail the "strictly greater than the average" condition.
Step 3: Scan upward until the candidate is absent
| Candidate | In set {2, 4, 5, 6}? | Action |
|---|---|---|
5 | Yes | Increment to 6 |
6 | Yes | Increment to 7 |
7 | No | Return 7 ✓ |
The answer is 7: it is strictly greater than 4.25 and does not appear in the array.
A second case — negative average, nums = [-3, -6]:
- Sum:
-9, floor division:-9 // 2 = -5(Python floors toward negative infinity), plus one gives-4. - The clamp kicks in:
max(1, -4) = 1, soans = 1. 1is not in{-3, -6}, so the loop exits immediately and returns1.
This second case highlights why the max(1, ...) clamp matters: without it, the candidate would start at -4, which violates the positivity requirement even though it exceeds the average.
Solution Implementation
1class Solution:
2 def smallestAbsent(self, nums: List[int]) -> int:
3 # Store all numbers in a set for O(1) membership lookups
4 num_set = set(nums)
5
6 # Compute the floor of the average, then add 1 to get the smallest
7 # integer strictly greater than the average.
8 # Clamp the result to at least 1, since the answer must be positive.
9 candidate = max(1, sum(nums) // len(nums) + 1)
10
11 # Increment the candidate until it is not present in the array
12 while candidate in num_set:
13 candidate += 1
14
15 return candidate
161class Solution {
2 public int smallestAbsent(int[] nums) {
3 // Store all elements in a hash set for O(1) lookups
4 Set<Integer> numSet = new HashSet<>();
5 int sum = 0;
6
7 // Build the set and accumulate the total sum in a single pass
8 for (int num : nums) {
9 numSet.add(num);
10 sum += num;
11 }
12
13 // The candidate must be a positive integer strictly greater
14 // than the average, so start from max(1, average + 1)
15 int candidate = Math.max(1, sum / nums.length + 1);
16
17 // Increment the candidate until we find a value
18 // that does not appear in the array
19 while (numSet.contains(candidate)) {
20 ++candidate;
21 }
22
23 return candidate;
24 }
25}
261class Solution {
2public:
3 int smallestAbsent(vector<int>& nums) {
4 // Store all elements in a hash set for O(1) lookups
5 unordered_set<int> numSet;
6 // Accumulate the sum of all elements
7 int totalSum = 0;
8 for (int num : nums) {
9 numSet.insert(num);
10 totalSum += num;
11 }
12
13 // Compute the average (integer division) of the array.
14 // The answer must be a positive integer strictly greater than the average,
15 // so start searching from max(1, average + 1).
16 int candidate = max(1, totalSum / static_cast<int>(nums.size()) + 1);
17
18 // Increment the candidate until we find a value not present in the array
19 while (numSet.contains(candidate)) {
20 ++candidate;
21 }
22
23 return candidate;
24 }
25};
261/**
2 * Finds the smallest positive integer that is strictly greater than
3 * the average of all elements in `nums` and does not appear in `nums`.
4 *
5 * Steps:
6 * 1. Store all numbers in a hash set for O(1) lookups.
7 * 2. Compute the sum of all elements to derive the average.
8 * 3. Start from the first candidate: the larger of 1 and floor(average) + 1.
9 * 4. Increment the candidate until it is absent from the set.
10 *
11 * Time complexity: O(n + k), where n is the array length and
12 * k is the number of candidates checked.
13 * Space complexity: O(n) for the hash set.
14 *
15 * @param nums - The input array of integers.
16 * @returns The smallest absent integer greater than the average.
17 */
18function smallestAbsent(nums: number[]): number {
19 // Hash set for constant-time membership checks
20 const numSet = new Set<number>(nums);
21
22 // Sum of all elements, used to compute the average
23 const totalSum = nums.reduce((acc, cur) => acc + cur, 0);
24
25 // The answer must be a positive integer strictly greater than the average,
26 // so start from max(1, floor(average) + 1)
27 let candidate = Math.max(1, Math.floor(totalSum / nums.length) + 1);
28
29 // Move forward until the candidate is not present in the array
30 while (numSet.has(candidate)) {
31 candidate++;
32 }
33
34 return candidate;
35}
36Time and Space Complexity
-
Time Complexity:
O(n), wherenis the length of the arraynums. Building the setsand computingsum(nums)each takeO(n)time. Thewhileloop incrementsansonly while it exists ins; sincescontains at mostndistinct values, the loop executes at mostn + 1iterations, with each membership checkans in stakingO(1)on average. Therefore, the total time isO(n) + O(n) + O(n) = O(n). -
Space Complexity:
O(n). The setsstores up tondistinct elements fromnums, which dominates the extra space used. All other variables (ans, intermediate results) require onlyO(1)additional space.
Pattern Learn more about how to find time and space complexity quickly.
Common Pitfalls
Pitfall 1: Mishandling an average that is an exact integer
A frequent mistake is to compute the starting candidate with math.ceil(sum(nums) / len(nums)), reasoning that "the answer is the ceiling of the average."
# WRONG
candidate = max(1, math.ceil(sum(nums) / len(nums)))
This works when the average is fractional (ceil(3.5) = 4 > 3.5 ✓), but breaks when the average is a whole number. For nums = [3, 5], the average is exactly 4, and ceil(4) = 4, which is equal to the average — not strictly greater. The condition demands strict inequality, so the correct starting point is 5 (and after skipping the present 5, the answer is 6).
Solution: Use floor(avg) + 1 instead, which is strictly greater than the average in both cases:
candidate = max(1, sum(nums) // len(nums) + 1)
- Fractional average
3.5→3 + 1 = 4 > 3.5✓ - Integer average
4→4 + 1 = 5 > 4✓
Pitfall 2: Negative averages and language-specific division semantics
The trick sum // len + 1 relies on floor division, which in Python rounds toward negative infinity (-5 // 2 == -3). When porting this solution to languages like Java, C++, or Go, integer division truncates toward zero (-5 / 2 == -2), producing a value one too large for negative non-exact averages and potentially yielding a candidate that is not strictly greater than... actually worse, a candidate that wastes correctness guarantees of the formula.
// WRONG in Java: -5 / 2 == -2, but floor(-2.5) == -3 int candidate = Math.max(1, sum / n + 1);
In this particular problem the max(1, ...) clamp often masks the bug (negative averages get clamped to 1 anyway), but the floor value itself is wrong, and the same pattern copied into a similar problem without the clamp will fail.
Solution: Compute a true floor explicitly, e.g. in Java:
int floorAvg = Math.floorDiv(sum, n); int candidate = Math.max(1, floorAvg + 1);
Also note: forgetting the max(1, ...) clamp entirely is its own bug — for nums = [-1, -2, -3] the formula alone gives -2 + 1 = -1, a non-positive starting point, and the loop could return a negative "answer."
Pitfall 3: Floating-point comparison instead of integer arithmetic
Some implementations compute the average as a float and compare candidates against it directly:
# RISKY
avg = sum(nums) / len(nums)
candidate = 1
while candidate in num_set or candidate <= avg:
candidate += 1
Beyond being slower (it may iterate from 1 all the way up past a large average), this introduces floating-point precision risk: for large sums, sum(nums) / len(nums) may not be exactly representable, and a comparison like candidate <= avg can be decided incorrectly at the boundary, off by one.
Solution: Stay in integer arithmetic. The strict inequality candidate > sum/len is exactly equivalent to the overflow-free, precision-free integer test candidate * len(nums) > sum(nums), or more simply, start directly from sum(nums) // len(nums) + 1 as the reference solution does.
Ready to land your dream job?
Unlock your dream job with a 5-minute quiz for a personalized study roadmap!
Get My RoadmapWhich of the following shows the order of node visit in a Breadth-first Search?

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!