Simplify Path
Problem statement
You get an absolute Unix-style file path as a string. It always starts with /, but it may be messy: repeated slashes, a trailing slash, . segments and .. segments. Return the canonical version of the path, following these rules:
- Several slashes in a row count as a single
/. .means "this directory" and is dropped...means "go up one directory". At the root, there is nothing above, so..does nothing.- Any other segment is an ordinary directory name, including odd ones like
...or.git. - The result starts with exactly one
/, has single slashes between names, and has no trailing slash (unless the result is the root,/).
Examples
Example 1
Input: path = "/var//log/./nginx/../app/"
Output: "/var/log/app"
Explanation: The double slash collapses, . is dropped, and .. cancels nginx.
Example 2
Input: path = "/../etc/.../conf/"
Output: "/etc/.../conf"
Explanation: .. at the root has no effect, and ... is a normal directory name.
Hints
Approach
Walk the segments once and keep the directories you are currently "inside" on a stack.
- Split the path on
/. - For each segment:
- empty or
.: skip it; ..: pop the top of the stack if the stack is not empty;- anything else: push it.
- empty or
- The stack now holds the directories from root to leaf. Join them with
/and prefix a single/. An empty stack gives/.
Each segment is pushed and popped at most once, so the whole pass is linear in the length of the path.
O(n)Space O(n)class Solution: def simplifyPath(self, path: str) -> str: stack = [] for part in path.split("/"): if part == "..": if stack: stack.pop() elif part and part != ".": stack.append(part) return "/" + "/".join(stack)Follow-up questions
- Accept a relative path plus a current working directory, and return the absolute canonical path.
- Some directories are symbolic links given in a dictionary. How does resolving them change your approach?
Frequently asked questions
Normalising paths is a real safety step. A file server, artifact store or config-sync tool must resolve .. before checking a requested path against an allowed directory, otherwise /srv/files/../../etc/shadow slips past a naive prefix check.
No. Only exactly . and exactly .. have meaning. Anything else, including ... or ..hidden, is a regular directory name and must be kept.
In real code you should. In an interview the point is to show you can build it, and the library versions differ in edge cases: for example, normpath keeps a leading // on POSIX, which this problem does not allow.