Facebook Pixel

2148. Count Elements With Strictly Smaller and Greater Elements

Problem Description

You are given an integer array nums. Your task is to count how many elements in the array have both a strictly smaller element AND a strictly greater element that also appear somewhere in the array.

In other words, for an element to be counted:

  • There must be at least one element in nums that is strictly less than it
  • There must be at least one element in nums that is strictly greater than it

The solution works by finding the minimum value mi and maximum value mx in the array. Then it counts all elements x where mi < x < mx. This works because:

  • Any element equal to the minimum value cannot have a smaller element in the array
  • Any element equal to the maximum value cannot have a greater element in the array
  • All elements strictly between the minimum and maximum will have both smaller and greater elements present

For example, if nums = [3, 1, 5, 1, 3]:

  • Minimum is 1, maximum is 5
  • Elements strictly between 1 and 5 are: two occurrences of 3
  • So the answer is 2
Quick Interview Experience
Help others by sharing your interview experience
Have you seen this problem before?

Intuition

The key insight is recognizing that we don't need to check every element against every other element to find which ones have both smaller and greater values.

Think about the extreme elements in the array - the minimum and maximum values. The minimum value can never have an element smaller than it (by definition), so it can never be counted. Similarly, the maximum value can never have an element greater than it, so it also can never be counted.

Now consider any element that's not at these extremes - any element strictly between the minimum and maximum. Such an element is guaranteed to have:

  • At least one smaller element (the minimum value itself)
  • At least one greater element (the maximum value itself)

This means we can simplify our problem dramatically. Instead of checking each element to see if it has both smaller and greater elements in the array, we just need to:

  1. Find the minimum value mi and maximum value mx
  2. Count all elements where mi < x < mx

This transforms what could be an O(nΒ²) problem (checking each element against all others) into an O(n) problem (one pass to find min/max, one pass to count valid elements).

The elegance of this approach lies in recognizing that the existence of smaller and greater elements is determined entirely by an element's relationship to the array's extremes.

Learn more about Sorting patterns.

Solution Approach

The implementation follows a straightforward two-step process:

Step 1: Find the minimum and maximum values

We use Python's built-in min() and max() functions to find the smallest and largest elements in the array:

mi, mx = min(nums), max(nums)

This requires one pass through the array for each function, giving us O(n) time complexity for this step.

Step 2: Count elements strictly between min and max

We use a generator expression with the sum() function to count how many elements satisfy the condition mi < x < mx:

return sum(mi < x < mx for x in nums)

This works because:

  • The expression mi < x < mx evaluates to True (which equals 1) when x is strictly between the minimum and maximum
  • It evaluates to False (which equals 0) otherwise
  • sum() adds up all these 1s and 0s, effectively counting the True cases

The generator expression iterates through each element in nums exactly once, checking if it falls strictly between mi and mx. This is another O(n) operation.

Time Complexity: O(n) where n is the length of the array - we traverse the array three times (once for min, once for max, once for counting)

Space Complexity: O(1) - we only use two variables (mi and mx) regardless of input size

The beauty of this solution is its simplicity - by identifying that only elements strictly between the minimum and maximum can satisfy the condition, we avoid nested loops and achieve optimal linear time complexity.

Ready to land your dream job?

Unlock your dream job with a 5-minute evaluator for a personalized learning plan!

Start Evaluator

Example Walkthrough

Let's walk through the solution with nums = [11, 7, 2, 15, 7]:

Step 1: Find the minimum and maximum values

  • Scan through the array: [11, 7, 2, 15, 7]
  • Minimum value mi = 2
  • Maximum value mx = 15

Step 2: Count elements strictly between min and max

  • Check each element to see if 2 < x < 15:
    • x = 11: Is 2 < 11 < 15? Yes βœ“ (count = 1)
    • x = 7: Is 2 < 7 < 15? Yes βœ“ (count = 2)
    • x = 2: Is 2 < 2 < 15? No βœ— (2 is not strictly greater than 2)
    • x = 15: Is 2 < 15 < 15? No βœ— (15 is not strictly less than 15)
    • x = 7: Is 2 < 7 < 15? Yes βœ“ (count = 3)

Result: 3 elements satisfy the condition

Let's verify our answer makes sense:

  • The element 11 has smaller elements (7, 2) and a greater element (15) βœ“
  • The first 7 has a smaller element (2) and greater elements (11, 15) βœ“
  • The element 2 (minimum) has no smaller elements βœ—
  • The element 15 (maximum) has no greater elements βœ—
  • The second 7 has a smaller element (2) and greater elements (11, 15) βœ“

The count of 3 matches our expectation - only the elements strictly between the minimum and maximum have both smaller and greater elements in the array.

Solution Implementation

1class Solution:
2    def countElements(self, nums: List[int]) -> int:
3        """
4        Count the number of elements that are strictly between the minimum and maximum values.
5      
6        Args:
7            nums: List of integers
8          
9        Returns:
10            Count of elements that are greater than the minimum and less than the maximum
11        """
12        # Find the minimum and maximum values in the array
13        min_value = min(nums)
14        max_value = max(nums)
15      
16        # Count elements that are strictly between min and max
17        # Using generator expression with sum to count True values (True = 1, False = 0)
18        count = sum(min_value < num < max_value for num in nums)
19      
20        return count
21
1class Solution {
2    /**
3     * Counts the number of elements that are strictly between the minimum and maximum values.
4     * An element is counted if it is greater than the minimum and less than the maximum.
5     * 
6     * @param nums the input array of integers
7     * @return the count of elements strictly between min and max
8     */
9    public int countElements(int[] nums) {
10        // Find the minimum value in the array
11        int minValue = Arrays.stream(nums).min().getAsInt();
12      
13        // Find the maximum value in the array
14        int maxValue = Arrays.stream(nums).max().getAsInt();
15      
16        // Initialize counter for elements between min and max
17        int count = 0;
18      
19        // Iterate through each element in the array
20        for (int num : nums) {
21            // Check if current element is strictly between min and max
22            if (minValue < num && num < maxValue) {
23                count++;
24            }
25        }
26      
27        // Return the final count
28        return count;
29    }
30}
31
1class Solution {
2public:
3    int countElements(vector<int>& nums) {
4        // Find the minimum and maximum elements in the array
5        // minmax_element returns a pair of iterators pointing to min and max elements
6        auto [minIter, maxIter] = ranges::minmax_element(nums);
7      
8        // Count elements that are strictly between the minimum and maximum values
9        // Using count_if with a lambda function to check the condition
10        return ranges::count_if(nums, [minIter, maxIter](int x) { 
11            // Element must be greater than min AND less than max
12            return *minIter < x && x < *maxIter; 
13        });
14    }
15};
16
1/**
2 * Counts the number of elements in the array that are strictly between 
3 * the minimum and maximum values.
4 * 
5 * @param nums - The input array of numbers
6 * @returns The count of elements strictly between min and max values
7 */
8function countElements(nums: number[]): number {
9    // Find the minimum value in the array
10    const minValue: number = Math.min(...nums);
11  
12    // Find the maximum value in the array
13    const maxValue: number = Math.max(...nums);
14  
15    // Filter elements that are strictly greater than min and strictly less than max
16    // Then return the count of such elements
17    return nums.filter((element: number) => minValue < element && element < maxValue).length;
18}
19

Time and Space Complexity

The time complexity is O(n), where n is the length of the array nums. This is because:

  • Finding the minimum value using min(nums) requires traversing all n elements once: O(n)
  • Finding the maximum value using max(nums) requires traversing all n elements once: O(n)
  • The generator expression sum(mi < x < mx for x in nums) iterates through all n elements once to count elements strictly between the minimum and maximum: O(n)
  • Total: O(n) + O(n) + O(n) = O(3n) = O(n)

The space complexity is O(1). This is because:

  • The variables mi and mx store single integer values, using constant space
  • The generator expression in sum() doesn't create an intermediate list but evaluates elements one by one
  • No additional data structures are created that scale with the input size
  • Only a constant amount of extra space is used regardless of the input size

Learn more about how to find time and space complexity quickly.

Common Pitfalls

1. Handling Arrays with All Same Elements

A common oversight is not considering what happens when all elements in the array are identical. In this case, min_value == max_value, and no element can satisfy min_value < num < max_value.

Example:

nums = [5, 5, 5, 5]
# min_value = 5, max_value = 5
# No element can be strictly between 5 and 5
# Expected output: 0

Solution: The current implementation handles this correctly since the condition min_value < num < max_value will never be true when min equals max. No special handling needed, but it's important to test this edge case.

2. Confusion Between "Different Elements" vs "Different Values"

Developers might misinterpret the problem as requiring different element positions rather than different values. The problem asks if there exists at least one smaller and one greater value in the array, not necessarily at different indices.

Example:

nums = [1, 2, 2, 3]
# Both 2s should be counted since 1 < 2 < 3
# Correct output: 2 (both occurrences of 2)
# Wrong interpretation might count only 1

Solution: The implementation correctly counts all occurrences of values between min and max, not unique values.

3. Attempting to Optimize with Early Termination

Some might try to "optimize" by stopping early if they find min == max:

# Incorrect "optimization"
def countElements(self, nums: List[int]) -> int:
    if len(nums) <= 2:  # Wrong assumption!
        return 0
    min_value = min(nums)
    max_value = max(nums)
    if min_value == max_value:  # Unnecessary check
        return 0
    return sum(min_value < num < max_value for num in nums)

Problem: The length check is incorrect - an array like [1, 2, 3] has length 3 and should return 1, not 0.

Solution: Stick with the simple implementation. The overhead of additional checks often isn't worth the complexity, and the condition naturally handles edge cases.

4. Using Set for "Optimization" Without Considering Duplicates

Converting to a set might seem like an optimization but loses count information:

# Incorrect approach
def countElements(self, nums: List[int]) -> int:
    unique_nums = set(nums)  # Loses duplicate counts!
    min_value = min(unique_nums)
    max_value = max(unique_nums)
    return sum(min_value < num < max_value for num in unique_nums)

Example where this fails:

nums = [1, 2, 2, 2, 3]
# Correct answer: 3 (three 2s)
# Wrong answer with set: 1 (only one 2 in the set)

Solution: Work with the original array to preserve duplicate counts, as the original implementation does.

Discover Your Strengths and Weaknesses: Take Our 5-Minute Quiz to Tailor Your Study Plan:

Consider the classic dynamic programming of fibonacci numbers, what is the recurrence relation?


Recommended Readings

Want a Structured Path to Master System Design Too? Don’t Miss This!

Load More