When beginning competitive programming, problems that seem mathematically simple often contain hidden traps. HackerRank's Min-Max Sum challenge is a perfect example of this.
The problem asks us to take five positive integers and calculate the minimum and maximum sums possible by combining exactly four of them. While the arithmetic is basic, the core challenge lies in understanding how data types handle large numerical boundaries.
For instance, when input integers approach one billion, summing them exceeds standard 32-bit storage limits. To write a production-ready solution, we must avoid numerical overflow. In this tutorial, we will explore both functional Stream-based reduction and optimized single-pass loops to solve this safely in Java.
To visualize the underlying math, imagine you have five physical weights sitting on a table: 1g, 2g, 3g, 4g, and 5g. You are asked to choose exactly four of these weights and calculate their combined weight.
- For the Minimum Sum: To obtain the lightest possible combination, you leave behind the single heaviest weight (
5g). The remaining weights sum to1 + 2 + 3 + 4 = 10g. - For the Maximum Sum: To obtain the heaviest possible combination, you leave behind the single lightest weight (
1g). The remaining weights sum to2 + 3 + 4 + 5 = 14g.
Instead of calculating every permutation of four weights, the most efficient method is to find the total sum of all five weights. From there:
Minimum Sum = Total Sum - Maximum ElementMaximum Sum = Total Sum - Minimum Element
Algorithmic Solutions & Integer Overflow
We can implement this logic in Java using two different coding styles:
- Functional Stream Reduction: We convert our list into a stream and apply
.reduce()operators to calculate the minimum value, maximum value, and overall sum. This declarative style is highly readable. - Greedy Single-Loop Pass: We loop through the list once, updating our running
minValueandmaxValuecheckers, while accumulating a running sum.
A standard 32-bit Java int supports values up to 2,147,483,647. If the five input values are large (such as 1,000,000,000), the sum becomes 5,000,000,000, which overflows the integer range and yields incorrect negative numbers.
To prevent this truncation, we must declare the sum using a 64-bit long data type, which supports values up to 9,223,372,036,854,775,807. Using long variables guarantees correct calculations.
Step-by-Step Scenario Trace
Let's trace a sample array: arr = [1, 3, 5, 7, 9]:
- Step 1 (Initialization): We set
minValue = 1,maxValue = 1,totalSum = 0. - Step 2 (Looping & Accumulation):
- For
1:totalSum = 1. Trackers remain unchanged. - For
3:totalSum = 4. Since3 > maxValue,maxValue = 3. - For
5:totalSum = 9. Since5 > maxValue,maxValue = 5. - For
7:totalSum = 16. Since7 > maxValue,maxValue = 7. - For
9:totalSum = 25. Since9 > maxValue,maxValue = 9.
- For
- Step 3 (Final Calculation):
Min Sum = 25 - 9 = 16(sum of1 + 3 + 5 + 7).Max Sum = 25 - 1 = 24(sum of3 + 5 + 7 + 9).
16 24.
Java Implementation Code
Below is the complete solution including input reading:
package io.practise.hackerrank;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;
import java.util.stream.Stream;
import static java.util.stream.Collectors.toList;
public class MinMaxSum {
public static void main(String[] args) throws IOException {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
List<Integer> arr = Stream.of(bufferedReader.readLine().replaceAll("\\s+$", "").split(" "))
.map(Integer::parseInt)
.collect(toList());
miniMaxSum(arr);
bufferedReader.close();
}
public static void miniMaxSum(List<Integer> arr) {
long minValue = arr.get(0);
long maxValue = arr.get(0);
long totalSum = 0;
for (int val : arr) {
totalSum += val; // Prevents overflow via long arithmetic
if (val < minValue) minValue = val;
if (val > maxValue) maxValue = val;
}
System.out.println((totalSum - maxValue) + " " + (totalSum - minValue));
}
}
Conclusion & Complexity Analysis
This greedy algorithm runs in O(N) linear time complexity (where N is the number of elements) and uses O(1) constant space. By utilizing the mathematical relationship between the total sum and extreme values, we solve the challenge in a single pass while using proper type declarations to avoid integer overflows.