Given a list of numbers, find the maximum and minimum values present in the list.
Example
Input: [10, 3, 56, 23, 0, -5, 56]
Output:
Maximum = 56
Minimum = -5
Approach
We can solve this problem in several ways: use Python’s built-in max() and min() functions for simplicity and readability; iterate through the list once to compute both values in O(n) time without extra space; or sort the list and pick the first and last elements (simpler but slower for large lists).
Method 1 — Using built-in max() and min()
Idea: Directly call max() and min() for a concise solution.
Code:
# Method 1: simplest — direct built-ins
nums = [10, 3, 56, 23, 0, -5, 56]
minimum = min(nums)
maximum = max(nums)
print("Minimum =", minimum)
print("Maximum =", maximum)
Explanation (2–4 lines): Using min() and max() directly is the simplest and most readable approach. Both functions scan the list once. They raise a ValueError for an empty list, so ensure the list is not empty before calling them.
Method 2 — Using built-in max() and min()
Idea: Directly call max(list) and min(list). This is the most readable and Pythonic approach.
Code:
# Method 1: built-in functions
def find_min_max_builtin(arr):
if not arr:
raise ValueError("Empty list has no min or max")
return min(arr), max(arr)
# Example usage
nums = [10, 3, 56, 23, 0, -5, 56]
minimum, maximum = find_min_max_builtin(nums)
print("Minimum =", minimum)
print("Maximum =", maximum)
Explanation (2–4 lines):min() and max() scan the iterable once and return the smallest and largest elements. They are concise and efficient for most use cases. If the list is empty, these functions raise a ValueError, so handle that case explicitly.
Method 3 — Single pass loop
Idea: Iterate through the list once, maintaining current min_val and max_val. This avoids creating extra copies or relying on built-ins.
Code:
# Method 2: single pass loop
def find_min_max_loop(arr):
if not arr:
raise ValueError("Empty list has no min or max")
min_val = max_val = arr[0]
for x in arr[1:]:
if x < min_val:
min_val = x
elif x > max_val:
max_val = x
return min_val, max_val
# Example usage
nums = [10, 3, 56, 23, 0, -5, 56]
minimum, maximum = find_min_max_loop(nums)
print("Minimum =", minimum)
print("Maximum =", maximum)
Explanation :
Initialize both min_val and max_val with the first element, then update them while scanning the rest. This guarantees a single pass (O(n)) and constant extra space.
Method 4 — Using sorted()
Idea: Sort the list and take the first (minimum) and last (maximum) elements. This is easy to write but slower for large lists.
Code:
# Method 4: sort the list
def find_min_max_sorted(arr):
if not arr:
raise ValueError("Empty list has no min or max")
s = sorted(arr)
return s[0], s[-1]
# Example usage
nums = [10, 3, 56, 23, 0, -5, 56]
minimum, maximum = find_min_max_sorted(nums)
print("Minimum =", minimum)
print("Maximum =", maximum)
Explanation :
Sorting places values in order; the smallest is at index 0 and the largest at index -1. Complexity is dominated by sorting (O(n log n)). Use this when you also need the list ordered.
Method 5 — Using functools.reduce()
Idea: Use reduce() to compute min and max by applying a comparison function cumulatively.
Code:
from functools import reduce
# reduce to get max
def find_max_reduce(arr):
if not arr:
raise ValueError("Empty list has no max")
return reduce(lambda a, b: a if a > b else b, arr)
# reduce to get min
def find_min_reduce(arr):
if not arr:
raise ValueError("Empty list has no min")
return reduce(lambda a, b: a if a < b else b, arr)
# Example usage
nums = [10, 3, 56, 23, 0, -5, 56]
print("Minimum =", find_min_reduce(nums))
print("Maximum =", find_max_reduce(nums))
Explanation :reduce() applies a binary function across the list to accumulate a single result. This is more functional but less direct than min()/max() or a loop.
Edge cases to consider
- Empty list: raise an error or decide on sentinel behavior.
- All elements equal: min and max are the same number.
- Lists with mixed numeric types (e.g.,
intandfloat) — Python supports comparison between them. - Lists with non-numeric comparable elements (e.g., strings) —
min()/max()still work lexicographically.
Time and Space Complexity
- Method 1 (built-ins simple): Time O(n), Space O(1) (ignoring iterator overhead).
- Method 2 (built-ins with function): Time O(n), Space O(1).
- Method 3 (single pass loop): Time O(n), Space O(1).
- Method 4 (sorted): Time O(n log n), Space O(n) if
sortedcreates a new list. - Method 5 (reduce): Time O(n), Space O(1) (function call overhead).
