Browse curriculum

Simplify Path

Turn a Unix-style absolute path into its canonical form with a stack of directory names: skip empty parts and '.', pop on '..', push names.

Problem Understanding

Simplify Path: given an absolute Unix-style path, return its canonical form. . means the current directory, .. the parent, and any run of slashes counts as one. The result starts with a single /, has no trailing slash, and contains no . or ...

Example: "/home/user/Documents/../Pictures" returns "/home/user/Pictures".

The Intuition: Where Am I Now?

Read the path left to right as a series of moves, keeping a stack of the directories you are inside:

  1. Empty part or .: you have not moved; ignore it. Empty parts come from //, the leading / and a trailing /.
  2. ..: go up a level; pop, unless you are already at the root.
  3. Anything else: a directory name, even ...; push it.

At the end the stack is the canonical path: join it with / and put a / in front. The same push-and-pop bookkeeping drives Valid Parentheses and Decode String.

Interactive Walkthrough

The parts of path.split('/') are on top, with empty parts drawn as "". Below them are the directories on the stack. When .. leaves a directory it turns red for one step. Try Above root to see .. ignored at the root.

Dry Run Table

Input: "/.../a/../b/c/../d/./"

Part Action Stack after
"" ignore []
... push [...]
a push [..., a]
.. pop a [...]
b push [..., b]
c push [..., b, c]
.. pop c [..., b]
d push [..., b, d]
. ignore [..., b, d]
"" ignore [..., b, d]

Answer: "/.../b/d".

The Solution Template

Split, then a stack of names. The C version uses strtok, which already skips empty parts.

Simplify Path Code
1var simplifyPath = function(path) {
2 const stack = [];
3 for (const part of path.split('/')) {
4 if (part === '' || part === '.') continue;
5 if (part === '..') {
6 stack.pop();
7 } else {
8 stack.push(part);
9 }
10 }
11 return '/' + stack.join('/');
12};

Edge Cases & Common Mistakes

  • .. at the root: ignore it; "/../" is "/".
  • Names made of dots: ... is a normal directory name; only . and .. are special.
  • Multiple slashes: "/a//b" splits into an empty part between the slashes; skip it.
  • Empty result: join gives an empty string; the answer is "/", not "".
  • JavaScript pop() on an empty array: returns undefined and changes nothing, so no guard is needed there.

Summary

Split the path on '/'. Ignore empty parts and '.', pop on '..' when the stack is not empty, and push every other name. Return '/' plus the stack joined with '/'. O(n) time, O(n) space.

More practice: DSA interview questions with answers · patterns cheat sheet

The approach, step by step

  1. Split the path

    Split on '/'. Doubled, leading and trailing slashes produce empty parts.

  2. Process each part

    Ignore empty parts and '.'. On '..', pop if the stack is not empty. Push any other name.

  3. Join

    Return '/' followed by the stack joined with '/'. An empty stack gives '/'.

Frequently asked questions

Why use a stack for Simplify Path?

Walking into a directory and walking back out with '..' is last-in, first-out: '..' always leaves the directory entered most recently. A stack of names models the current location exactly.


What happens with '..' at the root?

Nothing. The root has no parent, so '..' with an empty stack is ignored and the path stays at '/'.


Is '...' a special name?

No. Only '.' and '..' are special. Any other part, including '...' or '....', is an ordinary directory name and is pushed.

Applying for software engineering roles? Free, no sign-up:

AI resume checker — match your resume to the job description