Category: Easy | Concepts used: Array iteration, boundary limits, stream evaluation
Problem Statement
Given an array of integers, find the largest (max) and smallest (min) values.
Input : [3, 7, 1, 9, 4] Output: Max = 9, Min = 1
Input : [5] Output: Max = 5, Min = 5 (single element)
Examples (with edge scenarios)
| # | Input Array | Max | Min | Why |
|---|---|---|---|---|
| 1 | [3, 7, 1, 9, 4] | 9 | 1 | Typical positive array |
| 2 | [5] | 5 | 5 | Single element counts as both max and min |
| 3 | [-3, -7, -1] | -1 | -7 | Correctly identifies -1 as the largest negative value |
| 4 | [4, 4, 4] | 4 | 4 | Duplicate elements handled correctly |
| 5 | [] | N/A | N/A | Empty array check |
โ ๏ธ Common Beginner Mistake
Mistake Impact Fix Initializing max = 0andmin = 0Fails for negative arrays (e.g. [-5, -2]reports max as0)Initialize max = arr[0]andmin = arr[0]Not checking array bounds beforehand Throws ArrayIndexOutOfBoundsExceptionon empty arrays[]Handle arr.length == 0first
Before You Code: Clarify the Contract
Before choosing an algorithm, confirm whether the array may be null or empty, whether duplicates and original order matter, whether the method may modify the input, and whether the answer should contain values or original indices. These choices can change both the code and the best data structure.
Analogy: Spotting the Tallest and Shortest Student
Imagine you are a coordinator at a sports camp, and a line of students (an array of integers) walks in one by one. You want to identify the tallest and the shortest students:
- Before the first student walks in, you canโt assume anything.
- The first student walks in. Since they are the only student youโve seen, they are automatically the tallest (
max = arr[0]) and the shortest (min = arr[0]) so far. - The second student walks in. You compare them:
- If they are taller than your current record holder, they become the new tallest.
- If they are shorter than your current record holder, they become the new shortest.
- You repeat this comparison for each student in the line. By the time the last student is checked, you know exactly who is the tallest and shortest without ever needing to sort the line or check anyone twice!
Solution 1 โ Single Loop, Track Max and Min Together (Recommended)
This is the most efficient, linear approach.
Intuition
By walking through the array once and comparing each element against both max and min, we minimize comparisons and keep the time complexity strictly linear.
public class MaxMinArray {
public static void findMaxMin(int[] arr) {
if (arr == null || arr.length == 0) {
System.out.println("Array is empty!");
return;
}
// Initialize with first element, NOT 0
int max = arr[0];
int min = arr[0];
for (int i = 1; i < arr.length; i++) {
if (arr[i] > max) {
max = arr[i];
} else if (arr[i] < min) { // else-if is safe since an element cannot be both > max and < min
min = arr[i];
}
}
System.out.println("Max = " + max + ", Min = " + min);
}
public static void main(String[] args) {
findMaxMin(new int[]{3, 7, 1, 9, 4}); // Max = 9, Min = 1
findMaxMin(new int[]{5}); // Max = 5, Min = 5
findMaxMin(new int[]{-3, -7, -1}); // Max = -1, Min = -7
findMaxMin(new int[]{}); // Array is empty!
}
}
Output:
Max = 9, Min = 1
Max = 5, Min = 5
Max = -1, Min = -7
Array is empty!
Dry Run (arr = [3, 7, 1, 9, 4])
Start: max = 3, min = 3 (from arr[0])
i = 1: arr[1] = 7 -> 7 > 3 -> max = 7
i = 2: arr[2] = 1 -> 1 > 7 (false) -> 1 < 3 (true) -> min = 1
i = 3: arr[3] = 9 -> 9 > 7 -> max = 9
i = 4: arr[4] = 4 -> 4 > 9 (false) -> 4 < 1 (false)
Final: max = 9, min = 1
Solution 2 โ Using Java 8 Streams (Modern Java)
This solution utilizes Java 8โs functional streams for concise code.
Intuition
By using built-in terminal stream operators, we can extract the minimum and maximum elements in a declarative style.
import java.util.Arrays;
public class MaxMinStreams {
public static void findMaxMin(int[] arr) {
if (arr == null || arr.length == 0) {
System.out.println("Array is empty!");
return;
}
int max = Arrays.stream(arr).max().getAsInt();
int min = Arrays.stream(arr).min().getAsInt();
System.out.println("Max = " + max + ", Min = " + min);
}
public static void main(String[] args) {
findMaxMin(new int[]{3, 7, 1, 9, 4}); // Max = 9, Min = 1
}
}
Output:
Max = 9, Min = 1
๐ Visual Flowchart
graph TD
Start["Input Array arr"] --> CheckEmpty{"arr.length == 0?"}
CheckEmpty -->|Yes| RetError["Print: Array is empty!"]
CheckEmpty -->|No| Init["max = arr[0], min = arr[0]"]
Init --> Loop{"i < arr.length?"}
Loop -->|Yes| Fetch["num = arr[i]"]
Fetch --> CheckMax{"num > max?"}
CheckMax -->|Yes| UpdateMax["max = num"]
CheckMax -->|No| CheckMin{"num < min?"}
UpdateMax --> CheckMin
CheckMin -->|Yes| UpdateMin["min = num"]
CheckMin -->|No| IncLoop["i++"]
UpdateMin --> IncLoop
IncLoop --> Loop
Loop -->|No| Print["Print: max, min"]
Print --> End
Interviewer Insights
This is a core problem that evaluates optimal time efficiency and edge-case handling.
Follow-up questions you might get:
- โWhy is Solution 1 better than Arrays.sort()?โ โ Sorting requires (O(N \log N)) time complexity and rearranges elements. Solution 1 runs in linear (O(N)) time and leaves the source array unchanged.
- โHow can you reduce the number of comparison checks?โ โ You can compare elements in pairs instead of individually. By comparing
arr[i]andarr[i+1], and then comparing the larger withmaxand the smaller withmin, we reduce the total comparisons from (2N) to (\frac{3}{2}N).
Quick Recap
| Approach | Time Complexity | Space Complexity (Auxiliary) | Mutates Input? | Interview Signal |
|---|---|---|---|---|
| Single Loop | (O(N)) | (O(1)) | No | Highly optimal, industry standard |
| Java 8 Streams | (O(N)) | (O(1)) | No | Modern declarative Java, slightly higher abstraction overhead |
| Sort then Slice | (O(N \log N)) | (O(N)) (for copy) | If not copied | Sub-optimal, demonstrates basic API usage but poor performance |
- Author
- TechByteByByte Editorial Team
- Reviewed by
- TechByteByByte Admin
- Published
- Last reviewed