Baseball Game
Baseball Game: process a list of operations — a number, +, D, or C — against a record of scores, then return the sum of all scores that remain.
- 1 <= operations.length <= 1000
- operations[i] is "C", "D", "+", or a string representing an integer in [-3 * 10⁴, 3 * 10⁴]
- For "+" there will always be at least two previous scores
- For "C" and "D" there will always be at least one previous score
Intuition
Every operation refers only to the most recent scores, and C removes the last one — that is a stack, exactly. Once the record is modelled as a stack the four operations become one-line manipulations of its top, and the answer is the sum of whatever survives. Recognising the undo operation as a pop is what rules out an array with index arithmetic, which breaks as soon as a cancellation shifts the positions.
A stack is the answer whenever operations reference the most recent items and can be undone. The undo is the strongest signal — it is what makes position-based indexing fragile. Simplify Path and Remove All Adjacent Duplicates share the shape.
Approach
Before reading on: identify which operation forces a stack rather than a plain array with indices. Then decide how to distinguish an integer token from an operator, and check your method against the string "-2".
Why the record is a stack, not a list with indices
Three of the four operations reach backwards from the end: + reads the last two scores, D reads the last one, and C removes it. Nothing ever addresses a score by absolute position. The C operation is decisive — after a cancellation, every index-based reference to the previous score would need adjusting, whereas a stack's top pointer moves automatically. This is the general signal for a stack: the most recent item is the only one that matters, and it can be undone.
The four operations
An integer is pushed as a new score. + pushes the sum of the previous two scores, which requires reading the top two without removing them — pop-then-peek-then-push-back, or index from the end. D pushes double the previous score. C pops, invalidating the previous score entirely. The problem guarantees each operation is valid when it appears, so + always has two prior scores and C and D always have one, which is why no emptiness checks are needed.
Parsing and the final sum
The operations arrive as strings, so integers must be converted — and the parse must handle negatives, since scores can be below zero. Using str.isdigit() to detect a number is a subtle bug: it returns false for "-2", sending a negative score into the operator branches. Checking against the three known operators instead, and treating everything else as an integer, is both simpler and correct. After the pass, sum the stack; time is O(n) with each operation doing constant work, and space is O(n) for the record.
Solution & live demo
Common pitfalls
Detecting integers with isdigit
if op.isdigit():
record.append(int(op))if op not in ("+", "D", "C"):
record.append(int(op))isdigit returns False for "-2" because of the minus sign, so negative scores fall through to the operator branches and are silently mishandled or crash.
Reading the top two in the wrong order for +
record.append(record[0] + record[1])
record.append(record[-1] + record[-2])
The operation is defined on the two most recent scores, not the first two. Indexing from the front reads unrelated values and stops matching as soon as a C removes anything.
Removing the wrong entry on C
record.pop(0)
record.pop()
C invalidates the previous score, which is the last one recorded. Popping from the front removes the oldest score and corrupts every subsequent + and D.
Edge cases
Parsed as an integer; an isdigit check would misroute it.
The doubled score is removed, leaving the original intact.
Each pops one score, since the input guarantees validity.
Nothing assumes positivity; the sum is pushed as-is.
The stack empties and the total is 0.