1598. Crawler Log Folder - Explanation

Problem Link

Description

There is a file system that keeps a log each time some user performs a change folder operation.

The operations are described below:

  • "../" : Move to the parent folder of the current folder. (If you are already in the main folder, remain in the same folder).
  • "./" : Remain in the same folder.
  • "x/" : Move to the child folder named x (This folder is guaranteed to always exist).

You are given a list of strings logs where logs[i] is the operation performed by the user at the ith step.

The file system starts in the main folder, then the operations in logs are performed.

Return the minimum number of operations needed to go back to the main folder after the change folder operations.

Example 1:

Input: logs = ["d1/","d2/","../","d21/","./"]

Output: 2

Explanation: After all the log operations, use this change folder operation "../" 2 times and go back to the main folder.

Example 2:

Input: logs = ["d1/","../","../","../"]

Output: 0

Example 3:

Input: logs = ["d1/","d2/","../","d3/","../","d4/","../","d5/"]

Output: 2

Constraints:

  • 1 <= logs.length <= 1000
  • 2 <= logs[i].length <= 10
  • logs[i] contains lowercase English letters, digits, '.', and '/'.
  • logs[i] follows the format described in the statement.
  • Folder names consist of lowercase English letters and digits.


Topics

Company Tags

Please upgrade to NeetCode Pro to view company tags.



Prerequisites

Before attempting this problem, you should be comfortable with:

  • Stack Data Structure - Understanding push/pop operations and how stacks model nested or hierarchical state
  • String Comparison - Comparing strings for equality to distinguish between different folder operations

1. Stack

Intuition

A file system path can be naturally modeled using a stack. Moving into a folder pushes onto the stack, while moving to the parent folder pops from the stack. The operation "./" does nothing (stay in current folder). At the end, the stack's size represents how deep we are from the main folder, which equals the minimum operations needed to return.

Algorithm

  1. Initialize an empty stack.
  2. For each log operation:
    • If it is "../", pop from the stack if it is not empty (move to parent).
    • If it is "./", do nothing (stay in current folder).
    • Otherwise, push the folder name onto the stack (move into child folder).
  3. Return the size of the stack, representing the depth from the main folder.
class Solution:
    def minOperations(self, logs: List[str]) -> int:
        stack = []
        for log in logs:
            if log == "../":
                if stack:
                    stack.pop()
            elif log != "./":
                stack.append(log)
        return len(stack)

Time & Space Complexity

  • Time complexity: O(n)O(n)
  • Space complexity: O(n)O(n)

2. Iteration

Intuition

We do not actually need to store the folder names since we only care about the depth. A simple counter can track how many levels deep we are. Moving into a folder increments the counter, moving to parent decrements it (but never below 0 since we cannot go above the main folder), and "./" leaves it unchanged.

Algorithm

  1. Initialize a depth counter to 0.
  2. For each log operation:
    • If it is "./", skip (no change in depth).
    • If it is "../", decrement the counter but ensure it does not go below 0.
    • Otherwise, increment the counter (moving into a child folder).
  3. Return the counter value as the minimum operations to return to main folder.
class Solution:
    def minOperations(self, logs: List[str]) -> int:
        res = 0
        for log in logs:
            if log == "./":
                continue
            if log == "../":
                res = max(0, res - 1)
            else:
                res += 1
        return res

Time & Space Complexity

  • Time complexity: O(n)O(n)
  • Space complexity: O(1)O(1)

Common Pitfalls

Allowing Depth to Go Negative

When processing "../", you must ensure the depth does not go below zero. Going above the main folder is impossible, so decrementing when already at depth 0 produces wrong results.

# Wrong: depth can become negative
if log == "../":
    depth -= 1

# Correct: clamp at zero
if log == "../":
    depth = max(0, depth - 1)

Forgetting to Handle the Current Directory Operation

The operation "./" means stay in the current folder and should not change the depth. Treating it like a folder name and incrementing depth is a common mistake.

# Wrong: treating "./" as a folder
if log != "../":
    depth += 1  # This incorrectly increments for "./"

# Correct: explicitly skip "./"
if log == "./":
    continue
elif log == "../":
    depth = max(0, depth - 1)
else:
    depth += 1