Ugly Number II
Signals to notice
Brute force first
Check each number 1, 2, 3,.. for ugliness. Very slow for large n. That instinct is useful because it follows the prompt literally, but it usually keeps revisiting work the problem is begging you to organize.
The key insight
Three pointers: track the next ugly number to multiply by 2, 3, and 5. Take the minimum of the three candidates. Advance the pointer(s) that produced the minimum. 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
Every ugly number is 2, 3, or 5 times a previous ugly number. Three sorted sequences (ugly×2, ugly×3, ugly×5) are merged, and the minimum gives the next ugly number. If that remains true after every update, the rest of the reasoning has a stable place to stand.
Easy way to go wrong
Not advancing ALL pointers that match the minimum — if ugly[i2]×2 == ugly[i3]×3, advance both to avoid duplicates. Most mistakes here are not about syntax; they come from losing track of what your state, pointer, or structure is supposed to mean.