2733. Neither Minimum nor Maximum
Problem Description
You are given an integer array nums
that contains distinct positive integers. Your task is to find and return any number from the array that is neither the minimum value nor the maximum value. If no such number exists, return -1
.
The problem is asking you to:
- Identify the minimum and maximum values in the array
- Find any element that is not equal to either of these extreme values
- Return that element, or
-1
if all elements are either the minimum or maximum
For example:
- If
nums = [3, 1, 5, 2]
, the minimum is1
and maximum is5
. You can return either3
or2
since both are neither minimum nor maximum. - If
nums = [1, 2]
, the minimum is1
and maximum is2
. Since there are no other elements, return-1
. - If
nums = [5]
, there's only one element which is both minimum and maximum, so return-1
.
The solution approach finds the minimum and maximum values using min()
and max()
functions, then uses a generator expression with next()
to find the first element that doesn't equal either extreme value. If no such element exists, it returns the default value -1
.
Intuition
The key insight is that we need to find an element that falls between the minimum and maximum values. Since we're looking for any element that is neither the smallest nor the largest, we can think of this problem as finding a "middle" element.
The straightforward approach is to first identify what we need to avoid - the minimum and maximum values. Once we know these two values, we can scan through the array and pick the first element that doesn't match either of them.
Why does this work? Because if an array has at least 3 distinct elements, there must be at least one element that is neither the minimum nor the maximum. If the array has only 1 or 2 elements, then every element is either a minimum or maximum (or both), so we return -1
.
The solution uses next()
with a generator expression (x for x in nums if x != mi and x != mx)
which efficiently finds the first qualifying element without needing to check all elements. The second parameter -1
in next()
serves as a default value when no element satisfies our condition, which happens when the array has fewer than 3 distinct values.
This approach is optimal because:
- We must examine all elements at least once to find the minimum and maximum (no way around this)
- In the worst case, we might need to check all elements again to find a middle value
- The solution combines both steps efficiently in a single pass after finding min/max
Learn more about Sorting patterns.
Solution Approach
The implementation follows a simple two-step process:
Step 1: Find the minimum and maximum values
mi, mx = min(nums), max(nums)
We use Python's built-in min()
and max()
functions to find the smallest and largest values in the array. These functions iterate through the array once each, giving us O(n)
time complexity for this step.
Step 2: Search for a value that's neither minimum nor maximum
return next((x for x in nums if x != mi and x != mx), -1)
This line uses a generator expression combined with the next()
function:
(x for x in nums if x != mi and x != mx)
creates a generator that yields elements fromnums
that are neither equal tomi
normx
next()
retrieves the first value from this generator- The second parameter
-1
is the default value returned if the generator is empty (no elements satisfy the condition)
Why this works:
- If the array has 3 or more distinct elements, at least one element must be between the minimum and maximum values
- If the array has only 1 or 2 distinct elements, all elements are either minimum or maximum, so the generator produces nothing and
next()
returns-1
Time and Space Complexity:
- Time Complexity:
O(n)
wheren
is the length of the array. We traverse the array to find min/max, and potentially traverse it again to find a middle element. - Space Complexity:
O(1)
as we only use a constant amount of extra space for variablesmi
andmx
.
Ready to land your dream job?
Unlock your dream job with a 3-minute evaluator for a personalized learning plan!
Start EvaluatorExample Walkthrough
Let's walk through the solution with nums = [4, 2, 7, 1, 5]
:
Step 1: Find minimum and maximum
- We scan through the array to find
mi = min(nums) = 1
- We scan through the array to find
mx = max(nums) = 7
Step 2: Find an element that's neither min nor max
- We create a generator that will check each element:
- Check
4
: Is4 != 1
and4 != 7
? Yes! The generator yields4
next()
immediately returns this first yielded value:4
- Check
The function returns 4
(we could have also returned 2
or 5
, but 4
is encountered first).
Let's also see an example where we return -1
:
With nums = [3, 3]
:
Step 1: Find minimum and maximum
mi = min(nums) = 3
mx = max(nums) = 3
Step 2: Find an element that's neither min nor max
- We check each element:
- Check first
3
: Is3 != 3
and3 != 3
? No, skip - Check second
3
: Is3 != 3
and3 != 3
? No, skip
- Check first
- The generator yields nothing
next()
returns the default value:-1
This demonstrates how the solution efficiently handles both cases - when a middle element exists and when it doesn't.
Solution Implementation
1class Solution:
2 def findNonMinOrMax(self, nums: List[int]) -> int:
3 """
4 Find an element in the array that is neither the minimum nor the maximum.
5
6 Args:
7 nums: List of integers
8
9 Returns:
10 An element that is neither min nor max, or -1 if no such element exists
11 """
12 # Find the minimum and maximum values in the array
13 min_value = min(nums)
14 max_value = max(nums)
15
16 # Iterate through the array to find the first element that is neither min nor max
17 # Using a generator expression with next() for efficient early termination
18 result = next(
19 (num for num in nums if num != min_value and num != max_value),
20 -1 # Default value if no such element is found
21 )
22
23 return result
24
1class Solution {
2 /**
3 * Finds any element in the array that is neither the minimum nor the maximum value.
4 *
5 * @param nums The input array of integers
6 * @return An element that is neither min nor max, or -1 if no such element exists
7 */
8 public int findNonMinOrMax(int[] nums) {
9 // Initialize variables to track minimum and maximum values
10 // minValue starts at upper bound (100 based on problem constraints)
11 // maxValue starts at lower bound (0)
12 int minValue = 100;
13 int maxValue = 0;
14
15 // First pass: Find the minimum and maximum values in the array
16 for (int currentNum : nums) {
17 minValue = Math.min(minValue, currentNum);
18 maxValue = Math.max(maxValue, currentNum);
19 }
20
21 // Second pass: Find and return the first element that is neither min nor max
22 for (int currentNum : nums) {
23 if (currentNum != minValue && currentNum != maxValue) {
24 return currentNum;
25 }
26 }
27
28 // If no such element exists (e.g., all elements are the same or only two distinct values exist)
29 return -1;
30 }
31}
32
1class Solution {
2public:
3 int findNonMinOrMax(vector<int>& nums) {
4 // Find both minimum and maximum elements in the array simultaneously
5 auto [minIter, maxIter] = minmax_element(nums.begin(), nums.end());
6
7 // Iterate through the array to find an element that is neither min nor max
8 for (int num : nums) {
9 // If current element is not the minimum and not the maximum, return it
10 if (num != *minIter && num != *maxIter) {
11 return num;
12 }
13 }
14
15 // If no such element exists (all elements are either min or max), return -1
16 return -1;
17 }
18};
19
1function findNonMinOrMax(nums: number[]): number {
2 // Handle edge case: array with less than 3 elements cannot have a non-min/max value
3 if (nums.length < 3) {
4 return -1;
5 }
6
7 // Find the minimum and maximum values in the array
8 const minValue: number = Math.min(...nums);
9 const maxValue: number = Math.max(...nums);
10
11 // Iterate through the array to find an element that is neither min nor max
12 for (const num of nums) {
13 // If current element is not the minimum and not the maximum, return it
14 if (num !== minValue && num !== maxValue) {
15 return num;
16 }
17 }
18
19 // If no such element exists (all elements are either min or max), return -1
20 return -1;
21}
22
Time and Space Complexity
The time complexity is O(n)
, where n
is the length of the array. This is because:
min(nums)
traverses the entire array once:O(n)
max(nums)
traverses the entire array once:O(n)
- The generator expression
(x for x in nums if x != mi and x != mx)
in the worst case iterates through all elements:O(n)
- Overall:
O(n) + O(n) + O(n) = O(n)
The space complexity is O(1)
. The algorithm only uses a constant amount of extra space:
- Two variables
mi
andmx
to store the minimum and maximum values - The generator expression creates an iterator that yields values one at a time without storing the entire filtered list
- No additional data structures that scale with input size are created
Learn more about how to find time and space complexity quickly.
Common Pitfalls
1. Inefficient Multiple Passes Through the Array
A common pitfall is making unnecessary multiple passes through the array when the problem can be solved more efficiently.
Pitfall Example:
def findNonMinOrMax(self, nums: List[int]) -> int:
min_val = min(nums) # First pass
max_val = max(nums) # Second pass
# Third pass through entire array even if answer is found early
for num in nums:
if num != min_val and num != max_val:
return num
return -1
Better Solution: For small arrays or when we expect to find the answer quickly, we can optimize by combining operations:
def findNonMinOrMax(self, nums: List[int]) -> int:
if len(nums) < 3:
return -1 # Early termination for impossible cases
# Find min, max, and a middle value in a single pass
min_val = max_val = nums[0]
middle = -1
for num in nums:
if num < min_val:
middle = min_val # Previous min becomes a potential middle
min_val = num
elif num > max_val:
middle = max_val # Previous max becomes a potential middle
max_val = num
elif num != min_val and num != max_val:
return num # Found answer immediately
return middle if middle != -1 and middle != min_val and middle != max_val else -1
2. Not Handling Edge Cases Efficiently
Pitfall Example: Processing the entire array even when the array size makes it impossible to have a middle element:
def findNonMinOrMax(self, nums: List[int]) -> int:
min_val = min(nums) # Unnecessary computation for len <= 2
max_val = max(nums) # Unnecessary computation for len <= 2
# Rest of the logic...
Better Solution: Check array length first:
def findNonMinOrMax(self, nums: List[int]) -> int:
# Quick check for impossible cases
if len(nums) <= 2:
return -1
# For arrays with 3+ elements, we can even return early
# by sorting first 3 elements
first_three = sorted(nums[:3])
return first_three[1] # Middle element is guaranteed to be neither min nor max
3. Using Sorting When Not Necessary
Pitfall Example: Some might think to sort the entire array first:
def findNonMinOrMax(self, nums: List[int]) -> int:
nums_sorted = sorted(nums) # O(n log n) - unnecessary overhead
if len(nums_sorted) < 3:
return -1
return nums_sorted[1] # Return second element
Why it's a pitfall: Sorting takes O(n log n) time when the problem can be solved in O(n) time.
Better Solution: Stick with the linear time approach using min/max functions as shown in the original solution, or use the partial sorting approach shown above for just the first 3 elements when applicable.
Which data structure is used to implement priority queue?
Recommended Readings
Sorting Summary Comparisons We presented quite a few sorting algorithms and it is essential to know the advantages and disadvantages of each one The basic algorithms are easy to visualize and easy to learn for beginner programmers because of their simplicity As such they will suffice if you don't know any advanced
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!