Surrounded Regions
Signals to notice
Brute force first
For each 'O' region, check if it touches the border — due to repeated traversals. That direct path helps you understand the question, but it tends to treat every possibility as brand new instead of learning from earlier steps.
The key insight
Start from border 'O' cells and mark them as safe (flood fill). Then scan the grid: unmarked 'O' cells are surrounded (flip to 'X'), safe cells revert to 'O'. The goal is not to be clever for its own sake, but to remember the one relationship that keeps the solution grounded as you move forward.
What must stay true
A region of 'O' is captured if and only if it doesn't touch any border. Starting from border 'O' cells and marking connected 'O' cells as safe identifies exactly the uncapturable regions. As long as that statement keeps holding, you can trust the steps built on top of it.
Easy way to go wrong
Trying to identify surrounded regions by checking each 'O' cluster — it's easier to identify the UN-surrounded ones (those connected to the border) and capture everything else. Most mistakes here are not about syntax; they come from losing track of what your state, pointer, or structure is supposed to mean.