Simplify Path
Given an absolute Unix-style file path, return its simplified canonical form.
Open on LeetCode ↗Intuition
The tempting shortcut is to special-case anything that looks like dots, but ... is a perfectly ordinary directory name — only the exact token .. means go up, and treating triple-dot as special silently corrupts otherwise-valid paths. A path is really a sequence of directory pushes with .. as a pop, which makes a stack the natural model. Split on /, then classify each piece: empty or . is ignored, .. pops if anything is there, and anything else — however odd it looks — is pushed. Rejoin with / and prefix a slash.
Approach
Split and let empties fall out
path.split('/') on "/a//b" yields empty strings where consecutive or trailing slashes occurred. Rather than pre-cleaning the input, simply skip empty pieces during the scan — that handles every multiple-slash case at once.
Classify each component
"" and "." mean stay put, so skip them. ".." means go up, so pop the stack — but only if it is non-empty, since the root has no parent and /.. must stay /. Anything else is a directory name and gets pushed, including odd-looking ones like "...", which is a legal name and not a special token.
Rejoin
Return '/' + '/'.join(stack). An empty stack yields exactly "/", which is the correct canonical root, so no separate case is needed. The output has no trailing slash and no repeated separators. O(n) time and O(n) space.
Solution & live demo
Edge cases
The stack is empty so the pop is skipped and the result is "/".
Empty pieces are skipped, giving "/home/foo".
Two pops unwind a and b, leaving "/c".
Three dots is an ordinary directory name, not an up-level token — it is pushed.