Introduction
LeetCode 71: Simplify Path is a classic problem that mimics how Unix-style file systems handle file paths. Given a path, your goal is to simplify it by handling "."
, ".."
, and redundant slashes.
This is an excellent interview problem to demonstrate stack usage, string parsing, and edge case handling.
Problem Statement
Given a string path, which is an absolute path (starting with /
) for a file or directory in a Unix-style file system, simplify it and return the canonical path.
The canonical path should:
- Start with a single
/
.
- Eliminate multiple slashes (
//
becomes /
).
- Resolve
"."
(current directory).
- Resolve
".."
(parent directory).
- Not end with a trailing
/
(unless it's the root).
Examples:
go
Input: "/home/"
Output: "/home"
Input: "/../"
Output: "/"
Input: "/home//foo/"
Output: "/home/foo"
Input: "/a/./b/../../c/"
Output: "/c"
Approach: Using a Stack
To simplify the path:
- Split the path by
/
.
- Initialize an empty stack.
- Iterate through each part:
- If the part is
""
or "."
, skip it.
- If the part is
".."
and stack isn't empty, pop the last element (go up one level).
- Otherwise, push the directory name onto the stack.
- Join the stack with
/
and prepend /
to return the simplified path.
Go Implementation
go
func simplifyPath(path string) string {
parts := strings.Split(path, "/")
stack := []string{}
for _, part := range parts {
if part == "" || part == "." {
continue
} else if part == ".." {
if len(stack) > 0 {
stack = stack[:len(stack)-1]
}
} else {
stack = append(stack, part)
}
}
return "/" + strings.Join(stack, "/")
}
Explanation
strings.Split(path, "/")
breaks the path into components.
- We use a stack to build the simplified path.
".."
causes a pop if possible; "."
and empty strings are ignored.
- At the end, we join the stack with slashes and prepend
/
to form the canonical path.
Time and Space Complexity
MetricComplexityTime ComplexityO(n)Space ComplexityO(n)
Where n
is the length of the path string. Each part is visited once, and the stack holds at most n
components.
Edge Cases
- Multiple slashes:
"///"
→ simplified to "/"
- Redundant
.
directories: "/a/./b"
→ "/a/b"
- Going beyond root:
"/../../.."
→ "/"
- Trailing slash:
"/a/b/c/"
→ "/a/b/c"
Conclusion
LeetCode 71 tests your understanding of file system navigation and stack-based logic. It's a practical problem that often appears in technical interviews and helps reinforce string handling and algorithmic thinking.
Using Go's slice and string utilities, we can create a robust and clean solution that handles all edge cases efficiently.