Problem 2733

Abstract / Summary

Given a list of numbers, count how many are neither the smallest nor the largest value.

Note

The full problem description, including helpful examples, can be found on LeetCode.

Python 2733.py

class Solution:
    def findNonMinOrMax(self, nums: List[int]) -> int:
        low  = min(nums)
        high = max(nums)

        for n in nums:
            if low < n < high:
                return n

        return -1
10 lines | 230 bytes | submitted February 11, 2024 | GitHub   tab size 4 | low complexity

Difficulty

This problem is ranked as
easy medium hard

and has an acceptance rate of about 77% (100k+ submissions).

Typical patterns to solve this problem:
  • Array
  • Sorting
I solved 663 easy, 1250 medium and 309 hard problems

AI Disclaimer

Every single line of code was written by me, 100% from scratch, between August 2023 and August 2024.
However, two years later I set up this website and used various AI tools to generate most of the walkthrough / explanations below.

See this dedicated page for more details.
LeetCode profile | GitHub repo

Code Walkthrough

Overview

The provided implementation solves the problem of locating an element in an integer array that is neither the smallest nor the largest value. It returns the first such element encountered during a left-to-right scan, and if none exists it returns -1. The algorithm relies on Python’s built-in min and max functions to identify the extreme values, then performs a linear scan to find a qualifying element.

Key Steps

Determine the Minimum Value

The first operation extracts the smallest element from the input list.

low = min(nums)

min iterates over the list once and yields the lowest integer. Because it is a native C implementation, the operation is highly optimized for speed.

Determine the Maximum Value

Analogously, the largest element is obtained with:

high = max(nums)

Like min, max runs in a single pass and benefits from the same low-level optimizations.

Scan for a Non-Extremal Element

After the extremes are known, the code walks through the list in its original order, checking each element against the previously computed bounds.

for n in nums:
    if low < n < high:
        return n

The conditional low < n < high ensures that only values strictly between the minimum and maximum are considered. The moment such a value is found, the function returns it immediately, terminating the loop early.

Return Sentinel When No Candidate Exists

If the loop finishes without finding a qualifying element, the function falls back to a sentinel value:

return -1

This indicates that every element in the list is either equal to the minimum, equal to the maximum, or the list contains fewer than three distinct values.

Edge Cases Handled

When all numbers are identical, low and high are equal, making the condition low < n < high impossible to satisfy. The loop completes without a return, and the function yields -1.

If the list contains exactly two distinct values (for example, [1, 2, 1, 2]), each element is either the minimum or the maximum, so again no element meets the strict inequality and -1 is returned.

In a list where a qualifying element appears early (e.g., [5, 1, 3, 9]), the algorithm stops at the first occurrence (3) and does not continue scanning the remainder, demonstrating correct early-exit behavior.

When the list includes negative numbers or a mixture of positive and negative values, the built-in min and max correctly identify the extremes, and the subsequent comparison works without modification because it relies solely on numeric ordering.

Performance Optimizations Observed

The solution leverages Python’s highly tuned C-level implementations of min and max. These functions avoid Python-level overhead, making the identification of the extreme values faster than a manual loop written in pure Python.

The subsequent linear scan incorporates an early-return pattern. As soon as a suitable element is found, the function exits, preventing unnecessary iteration over the rest of the list. This is particularly beneficial for large inputs where a qualifying element appears near the beginning.

By separating the extreme-value computation from the search loop, the code avoids repeated comparisons against dynamic minima or maxima, which would increase the number of conditional checks per element. The fixed bounds (low and high) are computed once and reused, reducing per-iteration work.

Overall, the algorithm performs three passes over the data: one pass for min, one for max, and a final pass that may terminate early. The use of native functions and early termination together constitute the primary performance strengths of this implementation.

written by openai gpt

ELI5 - Simplified Explanation

Imagine you have a big treasure chest full of different number blocks. Some blocks are very small, and some blocks are very tall.

First, the code looks through the chest to find the very tiniest block and the very tallest block. It sets those aside because it is looking for something special. It wants to find a block that is not the smallest one and not the biggest one.

Next, it starts picking up each block in the chest one by one to check its size. It asks if a block is taller than the tiny one and shorter than the big one. If it finds a block that fits right in the middle, it holds that block up to show everyone that it found a perfect one.

If the code goes through the whole chest and does not find any block that is taller than the tiniest but shorter than the tallest, it stops looking and lets you know that it didn't find the special block you were looking for.

written by google gemini

Code Quality

Several LLMs ranked my code quality on a scale from 1 (very poor) to 10 (outstanding):
n = 26 | median = 7 | μ = 7.35 | σ = 1.17

Complexity Analysis

Time: linear
As a rule of thumb, the maximum input size for one second execution time is
  • factorial: up to 10 elements
  • exponential: up to 20 elements
  • polynomial: a few thousand elements
  • loglinear: up to 100,000 elements
  • linear: a few million elements
  • logarithmic: a billion elements
  • constant: practically unlimited
generated automatically

Other Solutions

I wrote a basic crawler to find other solutions to that problem.
Obviously, I did that after I solved the problem myself.

In general, AlgoMonster and WalkCCC solutions are high-quality and always worth a look.
I haven't checked most of the other solutions, but they might be helpful as well.

And of course, the LeetCode forum is always a good place (or even the best) to look for alternative approaches.

(click on a column header to sort the table)
author
author solutions
www AlgoMonster Java C++ Python TS
WalkCCC Java C++ Python
leetcode.ca Java Rust C++ Go Python
Progiez Java C++ Python
github charles-wangkai Java
fsq Rust
JoshCrozier JS
varunu28 Java
AlgoMonster C++, Python, Java, TypeScript
WalkCCC C++, Python, Java
leetcode.ca C++, Go, Java, Python, Rust
Progiez C++, Java, Python
charles-wangkai Java
fsq Rust
JoshCrozier JavaScript
varunu28 Java
19 links | 8 authors | 7 languages

Videos

3 videos   did my crawler come up with invalid videos ? drop me a line.

Similar Problems

1 similar problem

Solved On The Same Day

5 solutions   February 11, 2024

Extra

There are a few extra pages giving you some insights into my setup:
  • Tech Stack - my development environment and tools
  • AI - how AI helped me create this website (NOT solving the problems)
  • Progress - progression over time
  • Quality - code quality