Simplify Path
Overview
Simplify path: given a Unix path string, return the canonical path. Rules: "/" is separator; "." = current dir (ignore); ".." = parent (pop segment); multiple slashes = one; trailing/leading slashes normalized. Use a stack of path segments: split by "/", drop empty and "."; for ".." pop if non-empty; else push. Result = "/" + stack.join("/").
When to Use
- Canonical path from user input or concatenated paths.
- Navigate / resolve relative segments (..) against a base.
- Stack for "undo" levels β same push/pop on "..".
How It Works
Split path by "/", keep only non-empty and not ".". Stack = current directory stack. ".." pops one level (if any); any other segment pushes. Root is always "/"; no ".." above root.
Example 1: Split + Stack (Standard)
function simplifyPath(path: string): string {
const parts = path.split('/').filter(p => p !== '' && p !== '.');
const stack: string[] = [];
for (const p of parts) {
if (p === '..') { if (stack.length > 0) stack.pop(); }
else stack.push(p);
}
return '/' + stack.join('/');
}Time: O(n). Space: O(n).
Example 2: Step-by-Step Trace
"/a/./b/../../c/". Parts: ["a","b","..","..","c"]. Push a β [a]. Push b β [a,b]. ".." pop β [a]. ".." pop β []. Push c β [c]. Result "/c".
"/../" β parts [".."] β pop on empty stack (no-op) β [] β "/".
Example 3: Edge Cases
- "/" β parts [] β stack [] β "/".
- "/home/" β ["home"] β "/home".
- "/../../" β ["..",".."] β pop, pop β "/".
- "a/b/../c" (relative) β typically problem says absolute; if relative, stack starts empty, result "a/c" (no leading "/").
Example 4: Single Pass Without Split
Scan character by character (or by slash); build current segment; on "/" or end, if segment is ".." pop stack, else if segment and not "." push. Handle leading slash and empty segment. Same logic, O(n) one pass.
Example 5: Return Segments or No Leading Slash
If the API needs an array of segments: return stack (no join). If canonical form has no leading "/" for relative paths, use stack.join("/") without prefix when path was relative.
Summary
- Simplify path: split by "/", drop "" and "."; stack: ".." pop else push; result "/" + join. See Stack Basics.