Lesson 03new · v2 format
Trackers & Flags: Remembering What You've Seen
Totals, running best, found-flags and counters — the variables that carry information from one iteration to the next.
01Why it matters & the intuition
A loop body forgets everything when it finishes an iteration. Any variable declared before the loop is how information survives from one element to the next. Choosing that variable and giving it the right starting value is half of writing any algorithm — Kadane's, sliding window and DP are all built on it.
Think of it like…
A cricket scorer doesn't re-read the whole match after every ball. They keep a few running numbers — total runs, wickets, highest partnership — and update them ball by ball. Your tracker variables are that scorecard.
02The code blocks
Each block: the template in Python and C++, a line-by-line trace (press play and watch the highlighted line and the variables), the mistakes that cost the most debugging time, and a recall drill. Do the drill without scrolling up— that’s what makes it stick.
Block 1
Accumulator & counter
Use it for: Sums, averages, 'how many satisfy X', building totals for prefix sums.
1 · The template
total = 0
count = 0
for x in a:
if x > 0:
total += x
count += 12 · Watch it run, line by line
▶total = 02count = 03for x in a:4if x > 0:5total += x6count += 1
Variables
- total
- 0
3 · Classic mistakes
total = 0 inside the loopIt resets every iteration — initialise once, before the loop.int total (C++, big inputs)Sums of 10⁵ values up to 10⁹ overflow 32-bit int. Use long long.
4 · Recall it without looking
total =
for x in a:
total += xBlock 2
Running best (value + index)
Use it for: Max/min, best day to buy, longest streak so far, closest value, argmax.
1 · The template
best = a[0]
best_i = 0
for i in range(1, len(a)):
if a[i] > best:
best = a[i]
best_i = i2 · Watch it run, line by line
▶best = a[0]2best_i = 03for i in range(1, len(a)):4if a[i] > best:5best = a[i]6best_i = i
Variables
- best
- -4
3 · Classic mistakes
best = 0Wrong when every value is negative. Start from a[0] (or float('-inf') / INT_MIN).Updating best but not best_iThe two drift apart and you return the wrong position.
4 · Recall it without looking
best =
for i in range(, len(a)):
if a[i] > best:
best = a[i]Block 3
Flag + early exit
Use it for: Does any element match? Is the list sorted? Bubble sort's 'no swaps → done'.
1 · The template
found = False
for x in a:
if x == target:
found = True
break
print(found)2 · Watch it run, line by line
▶found = False2for x in a:3if x == target:4found = True5break6print(found)
Variables
- target
- 15
- found
- False
3 · Classic mistakes
else: found = False (inside the loop)A later non-match overwrites an earlier match. Only ever set the flag one way inside the loop.return inside a loop that should keep countingbreak / return are for 'answer known now'. For counts, let the loop finish.
4 · Recall it without looking
found = False
for x in a:
if x == target:
found = True
Block 4
Count occurrences (dict / map)
Use it for: Frequencies, anagrams, duplicates, majority element, 'first unique character'.
1 · The template
counts = {}
for x in a:
counts[x] = counts.get(x, 0) + 12 · Watch it run, line by line
▶counts = {}2for x in a:3counts[x] = counts.get(x, 0) + 1
Variables
- counts
- {}
3 · Classic mistakes
counts[x] += 1 (plain dict, first time)KeyError: the key doesn't exist yet. Use .get(x, 0) or collections.defaultdict(int).if x in list_of_seen:Membership in a list is O(n) — the whole loop becomes O(n²). Use a dict or set.
4 · Recall it without looking
counts = {}
for x in a:
counts[x] = counts.get(x, ) + 103Key ideas
Declare before, update inside, read after
Trackers live outside the loop. Initialise before, update in the body, use the result after the loop ends.
Pick the right starting value
Sum → 0, product → 1, max → a[0] or −∞, min → a[0] or +∞, found → False, count → 0. A wrong start value is a silent bug.
Flags answer yes/no; break saves time
Once the answer is certain, stop. break exits the innermost loop; inside a function, return exits everything.
Dict/map = a tracker per value
When you need a counter for every distinct value, use a dictionary. It's the bridge to the Hashing lessons.
04Cheat sheet
Every block from this lesson on one screen. Keep it open while you do the lab — then try the lab again without it.
total = 0 # sum
count = 0 # how many
best, best_i = a[0], 0 # running max + where
found = False # yes/no
for i in range(len(a)):
total += a[i]
if a[i] > 0:
count += 1
if a[i] > best:
best, best_i = a[i], i
if a[i] == target:
found = True # add break if nothing else needs the loop
counts = {} # frequency of every value
for x in a:
counts[x] = counts.get(x, 0) + 105Complexity
| Tracker | Time | Extra space |
|---|---|---|
| Sum / count / running best | O(n) | O(1) |
| Flag + break | O(n) worst, often much less | O(1) |
| Counting dict | O(n) average | O(k) for k distinct values |
06Check your understanding
07Code lab
Write Python(or switch to JavaScript) and run it against real test cases. Python runs inside your browser — nothing is uploaded — and a C++ reference solution is under “Solution”.
Second largest distinct value
Return the second largest distinct value in the list, or None (JS: None) if it doesn't exist. One pass with two trackers — no sorting.