Number Stack with a Bounded Type
Problem
Build a stack that only accepts numbers, and that can also tell the sum and the largest number it holds. Commands: push X, pop (print the removed number, or empty if the stack has none), sum (print the sum of all numbers; 0 for an empty stack), max (print the largest number, or empty).
Constraints
- 1 <= commands <= 100
- -10^9 <= X <= 10^9
Examples
Input
push 3 push 9 sum max
Output
12 9
Solutions
The bound T extends Number lets the class call number methods, and the compiler rejects a stack of strings. The class hides the list and gives only push, pop, sum and max.
/*
* Problem : Run the commands.
* Input : Command lines.
* Output : One line per answer.
* Approach: Bounded generic stack
* Time : O(n)
* Space : O(n)
* Java : 8 or newer.
*/
import java.util.Scanner;
public class Main {
// Step 1: T extends Number is a bound. Only number types fit, so the class may call longValue() on each item.
static class NumberStack<T extends Number> {
private final java.util.ArrayList<T> items = new java.util.ArrayList<T>();
void push(T value) {
items.add(value);
}
// Step 2: pop gives back null when the stack is empty.
T pop() {
return items.isEmpty() ? null : items.remove(items.size() - 1);
}
long sum() {
long total = 0;
for (T item : items) {
total += item.longValue();
}
return total;
}
T max() {
T best = null;
for (T item : items) {
if (best == null || item.longValue() > best.longValue()) {
best = item;
}
}
return best;
}
}
// This method solves the task. It receives the input and returns the answer.
static String[] solve(String[] lines) {
NumberStack<Long> stack = new NumberStack<Long>();
java.util.List<String> out = new java.util.ArrayList<String>();
for (String line : lines) {
String[] part = line.split(" ");
if (part[0].equals("push")) {
stack.push(Long.parseLong(part[1]));
} else if (part[0].equals("pop")) {
Long value = stack.pop();
out.add(value == null ? "empty" : String.valueOf(value));
} else if (part[0].equals("sum")) {
out.add(String.valueOf(stack.sum()));
} else {
Long value = stack.max();
out.add(value == null ? "empty" : String.valueOf(value));
}
}
return out.toArray(new String[0]);
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
java.util.List<String> all = new java.util.ArrayList<>();
while (scanner.hasNextLine()) {
String line = scanner.nextLine().trim();
if (!line.isEmpty()) {
all.add(line);
}
}
String[] lines = all.toArray(new String[0]);
System.out.println(String.join("\n", solve(lines)));
}
}
Hints (2)
- What does the bound allow the class to do?
- Why is pop allowed to return null?