Simplify Path

Medium
73.

Simplify Path

Simplify Path is a medium coding problem on strings and stack, asked in Capital One interviews.

Given an absolute Unix-style file path, return its canonical form:

  • Starts with a single /; directories separated by exactly one /; no trailing / (unless the result is the root).
  • . means current directory (ignored); .. moves up one level (the root's parent is the root).

Example 1

Input
path = "/home/"
Output
"/home"

Example 2

Input
path = "/../"
Output
"/"

Example 3

Input
path = "/home//foo/"
Output
"/home/foo"

Example 4

Input
path = "/a/./b/../../c/"
Output
"/c"

Constraints

  • 1 <= path.length <= 40
  • Letters, digits, '.', '/' and '_' only; always starts with '/'
Write your solution here. Running it against the tests needs a free account — what you type comes with you.Sign in to run
/**
 * @param {string} path
 * @return {string}
 */
var simplifyPath = function(path) {
    // Write your code here
    
};

Sign in to run your own test cases

Sign in

Simplify Path — Solution in Python, Java & C++

Simplify Path solution explained: step-by-step approach, complexity and code in Python, Java, C++ and JavaScript. A medium problem, asked at Capital One.

Simplify Path is a medium coding problem on strings and stack, asked in Capital One interviews.

  • Difficulty: Medium
  • Topics: Strings, Stack
  • Asked at: Capital One
  • Time limit: 2 s
  • Memory limit: 256 MB
  • Languages: JavaScript, TypeScript, Python, Java, C++, C, C#, Go, Kotlin, Swift, Rust, PHP and Ruby

Problem statement

Given an absolute Unix-style file path, return its canonical form:

  • Starts with a single /; directories separated by exactly one /; no trailing / (unless the result is the root).
  • . means current directory (ignored); .. moves up one level (the root's parent is the root).

Example 1

Input: path = "/home/"
Output: "/home"

Example 2

Input: path = "/../"
Output: "/"

Example 3

Input: path = "/home//foo/"
Output: "/home/foo"

Example 4

Input: path = "/a/./b/../../c/"
Output: "/c"

Constraints

  • 1 <= path.length <= 40
  • Letters, digits, '.', '/' and '_' only; always starts with '/'

Hints for Simplify Path

  1. Hint 1

    Split on '/' and process each token against a stack of directory names.

  2. Hint 2

    '..' pops (if possible); '.' and empty tokens are skipped; anything else pushes.

How to solve Simplify Path

A canonical path is just the list of directories you actually end up in. Splitting on / turns the path into tokens, and each token is one of four things: a real directory name (go in), .. (go up), . (stay), or empty (an artefact of // or a trailing slash). A stack of directory names models exactly that walk.

Approach

  1. Split the path on /. Runs of slashes and any trailing slash simply produce empty tokens.
  2. Skip every token that is empty or . — neither changes the directory.
  3. On .., pop the stack if it is non-empty. On the root, popping does nothing, which is the required behaviour.
  4. On anything else, push it as a directory name.
  5. Join the stack with / and prefix a single /. An empty stack gives "/" on its own.

Why it works

Splitting reduces every formatting quirk — doubled slashes, a trailing slash — to empty tokens, so the messy cases disappear before the logic runs. The stack then holds the current directory as an absolute chain from the root, and the join reconstructs it in canonical form: exactly one separator between names and no trailing slash, because the separators are inserted between elements.

Complexity

  • Time — O(n)
  • Space — O(n)

Pitfalls

  • .. at the root must be a no-op, not an error. (Python guards with if st; in JavaScript, pop() on an empty array is already harmless.)
  • Do not append a trailing / when joining — that is the whole point of the canonical form.
  • A directory name may legitimately contain dots, like ... or a.b; only exactly . and .. are special.

Reference solution

Python

def simplifyPath(path: str) -> str:
    st = []
    for part in path.split("/"):
        if part == "" or part == ".":
            continue
        if part == "..":
            if st:
                st.pop()
        else:
            st.append(part)
    return "/" + "/".join(st)

Java

public static String simplifyPath(String path) {
    List<String> st = new ArrayList<>();
    for (String part : path.split("/")) {
        if (part.isEmpty() || part.equals(".")) continue;
        if (part.equals("..")) {
            if (!st.isEmpty()) st.remove(st.size() - 1);
        } else {
            st.add(part);
        }
    }
    return "/" + String.join("/", st);
}

C++

string simplifyPath(string path) {
    vector<string> st;
    string cur;
    path += "/";
    for (char ch : path) {
        if (ch == '/') {
            if (cur == "..") {
                if (!st.empty()) st.pop_back();
            } else if (!cur.empty() && cur != ".") {
                st.push_back(cur);
            }
            cur.clear();
        } else {
            cur += ch;
        }
    }
    string out;
    for (size_t i = 0; i < st.size(); i++) {
        out += "/";
        out += st[i];
    }
    return out.empty() ? "/" : out;
}

JavaScript

var simplifyPath = function(path) {
    const st = [];
    for (const part of path.split("/")) {
        if (part === "" || part === ".") continue;
        if (part === "..") st.pop();
        else st.push(part);
    }
    return "/" + st.join("/");
};

Also on the editorial tab: C, C#, Go, Kotlin, PHP, Ruby, Rust, Swift, TypeScript.

All 515 strings problems · the whole catalogue

Learn the technique: Strings · Stack Data Structure