Simplify Path
The drill: Collapse a Unix-style absolute path into its canonical form: '.' does nothing, '..' pops back to the parent (never above root), and repeated slashes squeeze into one.
An absolute Unix-style file path arrives as a string, and the drill is to collapse it into its single canonical form.
A '.' component refers to the current directory and contributes nothing to the result. A '..' component steps up to the parent directory, but stepping up from the root simply stays at the root instead of erroring.
Multiple consecutive slashes collapse into one, and the canonical output always starts with a single leading slash, uses single slashes between directory names, and never ends with a trailing slash unless the whole result is just the root.
- path length can run into the thousands of characters
- directory and file names use ordinary path characters
- '..' at the root has no effect and never errors
- output always starts with exactly one leading slash
HINT 1 THE NUDGE
Split the path on '/' and look at each token in isolation — most of them are noise. What are the only three token shapes that actually matter?
HINT 2 THE STRUCTURE
A real '..' has to undo the most recently added real directory. That undo-the-most-recent shape is exactly what a stack is built for.
HINT 3 ONE STEP FROM THE ANSWER
Push every non-empty, non-'.' token; pop on '..' only if there's something to pop (root swallows extra '..'s). Join what's left with '/' and prefix it — default to '/' when the stack ends up empty.
Split the path on '/'. Real names push; '.' does nothing; '..' pops if there's something to pop.
class Solution:
def simplifyPath(self, path: str) -> str:
stack = []
for token in path.split("/"):
if token == "" or token == ".":
continue
elif token == "..":
if stack:
stack.pop()
else:
stack.append(token)
return "/" + "/".join(stack)class Solution:
def simplifyPath(self, path: str) -> str:
result = "" # canonical path rebuilt as a plain string, no stack
for token in path.split("/"):
if token == "" or token == ".":
continue
if token == "..":
if result:
result = result[: result.rfind("/")]
else:
result += "/" + token
return result if result else "/"class Solution {
public String simplifyPath(String path) {
Deque<String> stack = new ArrayDeque<>();
for (String token : path.split("/")) {
if (token.isEmpty() || token.equals(".")) {
continue;
} else if (token.equals("..")) {
if (!stack.isEmpty()) {
stack.pollLast();
}
} else {
stack.addLast(token);
}
}
StringBuilder sb = new StringBuilder();
for (String dir : stack) {
sb.append("/").append(dir);
}
return sb.length() == 0 ? "/" : sb.toString();
}
}class Solution {
public String simplifyPath(String path) {
StringBuilder result = new StringBuilder(); // canonical path rebuilt as a plain string, no stack
for (String token : path.split("/")) {
if (token.isEmpty() || token.equals(".")) {
continue;
}
if (token.equals("..")) {
if (result.length() > 0) {
result.setLength(result.lastIndexOf("/"));
}
} else {
result.append("/").append(token);
}
}
return result.length() == 0 ? "/" : result.toString();
}
}✓ CHIP-TIMED — ALL 4 SOLUTIONS RAN GREEN AGAINST SELF-AUTHORED CASES IN CI · JDK 21 · CPYTHON 3.12 · NOTHING PUBLISHES RED