You are given an absolute path for a Unix-style file system, which always begins with a slash '/'. Your task is to transform this absolute path into its simplified canonical path.
The rules of a Unix-style file system are as follows:
'.' represents the current directory.'..' represents the previous/parent directory.'//' and '///' are treated as a single slash '/'.'...' and '....' are valid directory or file names.The simplified canonical path should follow these rules:
'/'.'/'.'/', unless it is the root directory.'.' and '..') used to denote current or parent directories.Return the simplified canonical path.
Example 1:
Input: path = "/home/"
Output: "/home"
Explanation:
The trailing slash should be removed.
Example 2:
Input: path = "/home//foo/"
Output: "/home/foo"
Explanation:
Multiple consecutive slashes are replaced by a single one.
Example 3:
Input: path = "/home/user/Documents/../Pictures"
Output: "/home/user/Pictures"
Explanation:
A double period ".." refers to the directory up a level (the parent directory).
Example 4:
Input: path = "/../"
Output: "/"
Explanation:
Going one level up from the root directory is not possible.
Example 5:
Input: path = "/.../a/../b/c/../d/./"
Output: "/.../b/d"
Explanation:
"..." is a valid name for a directory in this problem.
Constraints:
1 <= path.length <= 3000path consists of English letters, digits, period '.', slash '/' or '_'.path is a valid absolute Unix path.Problem Overview: You receive an absolute Unix-style path such as /a/./b/../../c/ and must convert it into its canonical form. The canonical path removes redundant slashes, ignores . (current directory), and correctly handles .. (move to parent directory).
Approach 1: Using Stack Data Structure (Time: O(n), Space: O(n))
The most common solution processes directory segments using a stack. Split the input path by '/' and iterate through each token. Ignore empty strings and . because they represent the current directory. When encountering .., pop the last directory from the stack if one exists. Otherwise, push valid directory names onto the stack.
This works because the stack naturally models navigation through directories: pushing represents moving deeper into a folder, while popping represents returning to the parent directory. After processing all segments, join the stack contents with '/' and prepend a leading slash to build the canonical path. Parsing the string takes O(n) time where n is the path length, and the stack stores at most n characters overall, giving O(n) space.
Approach 2: Optimized String Handling (Time: O(n), Space: O(n))
This version avoids explicit stack APIs and relies on efficient string parsing with a dynamic list of path components. Scan the path character by character and build directory tokens manually. When a slash is encountered, process the collected token: ignore ., remove the last stored directory for .., or append the token if it represents a valid directory name.
The key idea is that you still maintain logical stack behavior, but operations happen directly on a list or string builder rather than a dedicated stack structure. This reduces overhead from repeated splits and can be faster for very long paths. The algorithm still touches each character once, resulting in O(n) time and O(n) auxiliary space for stored directories.
Recommended for interviews: The stack approach is what interviewers usually expect because it clearly demonstrates understanding of directory traversal rules and the natural LIFO behavior required for handling ... Showing the stack-based logic first proves correctness and clarity. The optimized parsing version demonstrates deeper understanding of string processing and performance tradeoffs.
This approach utilizes a stack data structure to process the path components. By splitting the path on the '/' character, we collect the different components of the path. Using a stack helps efficiently manage directory movement due to '..'. For every directory name, it is pushed to the stack, for '..' we pop from the stack, and '.' is simply ignored. After processing all components, we join the names in the stack with '/' to form the simplified canonical path.
The C implementation uses an array of strings as a stack to track directory parts. We split the path using '/' as a delimiter with the help of 'strtok'. For non-current ('.') and non-parent ('..') directory names, they are pushed to our stack. When '..' is encountered, we pop from the stack if the stack isn't empty. Lastly, we rebuild the canonical path by joining stack elements prefixed with '/'.
C++
Java
Python
C#
JavaScript
Time Complexity: O(N) where N is the length of the path string, as we perform operations linearly along the string.
Space Complexity: O(N) because we use a stack that can contain each part of the path in the worst case.
This approach optimizes the simplification process using string handling techniques without explicitly using stack structures. It involves maintaining a result string directly, with an index pointer to simulate stack behavior. Iterating over path components allows addition, removal, or skipping of segments based on path rules, with a focus on reducing stack overhead. Finally, the result string is reconstructed as the simplified path.
In this C solution, we manipulate raw strings to emulate stack-like behavior. For every component between slashes, we append to output or remove last appended segment based on Unix component rules. We directly construct the canonical path by modifying a result string in place.
C++
Java
Python
C#
JavaScript
Time Complexity: O(N) as parsing occurs once through entire path.
Space Complexity: O(N) utilized for the resultant path string (no explicit stack).
| Approach | Complexity |
|---|---|
| Using Stack Data Structure | Time Complexity: O(N) where N is the length of the path string, as we perform operations linearly along the string. |
| Optimized String Handling | Time Complexity: O(N) as parsing occurs once through entire path. |
| Approach | Time | Space | When to Use |
|---|---|---|---|
| Stack Data Structure | O(n) | O(n) | Best general solution; easiest to reason about directory navigation |
| Optimized String Handling | O(n) | O(n) | Useful when avoiding heavy string splitting or optimizing parsing |
Simplify Path - Stack - Leetcode 71 - Python • NeetCode • 73,047 views views
Watch 9 more video solutions →Practice Simplify Path with our built-in code editor and test cases.
Practice on FleetCode