LeetCode #682 Easy

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.

Constraints
  • 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
arraystacksimulation
Open on LeetCode ↗
Baseball Game diagramA labelled diagram of the structure this problem turns on.every operation reads or removes the most recent score51015the recordtop ↑intpush a new score+push sum of top twoDpush double the topCpop the topC is the decisive one — an undo is what makes indices fragile and a stack right
02

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.

How to spot this pattern

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.

03

Approach

Try it first

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".

1

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.

2

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.

3

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.

04

Solution & live demo

1class Solution:
2 def calPoints(self, operations):
3 record = []
4 for op in operations:
5 if op == "+":
6 record.append(record[-1] + record[-2])
7 elif op == "D":
8 record.append(record[-1] * 2)
9 elif op == "C":
10 record.pop()
11 else:
12 record.append(int(op))
13 return sum(record)
05

Common pitfalls

Detecting integers with isdigit

✗ Wrong
if op.isdigit():
    record.append(int(op))
✓ Right
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 +

✗ Wrong
record.append(record[0] + record[1])
✓ Right
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

✗ Wrong
record.pop(0)
✓ Right
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.

06

Edge cases

Negative score, e.g. "-2"

Parsed as an integer; an isdigit check would misroute it.

C immediately after a D

The doubled score is removed, leaving the original intact.

Consecutive C operations

Each pops one score, since the input guarantees validity.

+ producing a negative sum

Nothing assumes positivity; the sum is pushed as-is.

All scores cancelled

The stack empties and the total is 0.

07

Complexity

Time
O(n)
Space
O(n)
Each operation is constant time. The record holds at most one entry per operation.