Crawler Log Folder solution and explanation
9 more videos on this problem
Crawler Log Folder - Leetcode 1598 - PythonNeetCodeIO · 6:29 · 5K views
crawler log folder | crawler log folder leetcode | leetcode 1598Naresh Gupta · 4:00 · 2K views
1598. Crawler Log Folder | Stack | Array | O(1) SpaceAryan Mittal · 6:15 · 1K views
Crawler log folder | crawler log folder leetcode | leetcode 1598codedecks · 4:34 · 1K views
1598. Crawler Log Folder (Leetcode Easy)Programming Live with Larry · 3:29 · 405 views
Leetcode Solution - 1598 Crawler Log FolderJohn Leonardo · 4:04 · 318 views
1598. Crawler Log Folder | Easy Level Interview Question Full Explanation in PythonEduEverybody · 5:12 · 123 views
Crawler Log Folder||LeetCode 1598DSA Solutions · 4:26 · 66 views
Leetcode 1598. Crawler Log FolderFiveMinuteTimer · 7:04 · 59 views
1598. Crawler Log Folder | Leetcode | C++ | DSATechnosier · 10:39 · 56 views
The problem
The Leetcode file system 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 namedx(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: Use this change folder operation "../" 2 times and go back to the main folder.
Example 2:

Input: logs = ["d1/","d2/","./","d3/","../","d31/"] Output: 3
Example 3:
Input: logs = ["d1/","../","../","../"] Output: 0
Constraints:
1 <= logs.length <= 1032 <= logs[i].length <= 10logs[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.
Approach overview
Problem Overview: You are given a list of folder navigation logs such as "../", "./", or "x/". Each log represents moving up a directory, staying in the current folder, or entering a subfolder. The goal is to compute the minimum number of operations needed to return to the main folder after processing all logs.
The commands behave exactly like terminal navigation. "../" moves one level up (unless you are already at the root), "./" keeps you in the same directory, and any other string ending with "/" means entering a new folder. The problem becomes a simple state tracking task where you simulate how deep you are in the folder structure.
Approach 1: Using Depth Counter (O(n) time, O(1) space)
This approach keeps a single integer variable representing the current folder depth. Iterate through the array of logs and update the depth based on each command. When encountering "../", decrease the depth only if it is greater than zero. Ignore "./" because it does not change the directory. For any other log (like "d1/"), increment the depth because you move into a subfolder.
The key insight is that the actual folder names do not matter. Only the direction of movement matters. Because the algorithm processes each log once and stores only an integer counter, it runs in O(n) time with O(1) extra space. This is the simplest and most efficient solution and is typically what interviewers expect.
Approach 2: Using Stack for Folder Simulation (O(n) time, O(n) space)
This method simulates the directory structure using a stack. Traverse the logs one by one. When the command is a folder name like "x/", push it onto the stack. When the command is "../", pop from the stack if it is not empty. Ignore "./" since it keeps you in the same folder.
After processing all logs, the number of elements remaining in the stack represents how many directories deep you are from the root. That value equals the minimum operations needed to return to the main folder. This approach models the navigation process explicitly and mirrors how real file systems manage paths.
The stack-based solution also runs in O(n) time because each log is processed once. However, it uses O(n) space in the worst case if every log moves into a new folder. The logic relies heavily on operations typical in string processing and stack manipulation.
Recommended for interviews: The depth counter solution is usually preferred. It shows that you recognized the problem only tracks folder depth rather than actual paths. The stack approach is still valuable because it demonstrates understanding of directory simulation and stack-based state management.
Approach 1: Using Depth Counter
This approach involves maintaining a counter to keep track of the current folder depth. For each log operation, adjust the counter accordingly:
- For "x/" operations, increment the counter since we're going deeper into the directory structure.
- For "../" operations, decrement the counter but ensure it doesn't go below zero since we can't go above the root directory.
- For "./", do nothing as it indicates staying in the same directory.
After processing all the logs, the counter will give the minimum operations needed to return to the main folder, as it represents the current depth.
def min_operations(logs):
depth = 0
for log in logs:
if log == "../":
if depth > 0:
depth -= 1
elif log == "./":
continue
else:
depth += 1
return depth
logs = ["d1/", "d2/", "../", "d21/", "./"]
print(min_operations(logs))public class Solution {
public int minOperations(String[] logs) {
int depth = 0;
for (String log : logs) {
if (log.equals("../")) {
if (depth > 0) depth--;
} else if (!log.equals("./")) {
depth++;
}
}
return depth;
}
public static void main(String[] args) {
Solution solution = new Solution();
String[] logs = {"d1/", "d2/", "../", "d21/", "./"};
System.out.println(solution.minOperations(logs));
}
}#include <vector>
#include <string>
#include <iostream>
using namespace std;
int minOperations(vector<string>& logs) {
int depth = 0;
for (const string& log : logs) {
if (log == "../") {
if (depth > 0) depth--;
} else if (log == "./") {
continue;
} else {
depth++;
}
}
return depth;
}
int main() {
vector<string> logs = {"d1/", "d2/", "../", "d21/", "./"};
cout << minOperations(logs) << endl;
return 0;
}function minOperations(logs) {
let depth = 0;
for (const log of logs) {
if (log === "../") {
if (depth > 0) depth--;
} else if (log !== "./") {
depth++;
}
}
return depth;
}
const logs = ["d1/", "d2/", "../", "d21/", "./"];
console.log(minOperations(logs));#include <stdio.h>
#include <string.h>
int minOperations(char **logs, int logsSize) {
int depth = 0;
for (int i = 0; i < logsSize; i++) {
if (strcmp(logs[i], "../") == 0) {
if (depth > 0) depth--;
} else if (strcmp(logs[i], "./") == 0) {
continue;
} else {
depth++;
}
}
return depth;
}
int main() {
char *logs[] = {"d1/", "d2/", "../", "d21/", "./"};
int logsSize = sizeof(logs) / sizeof(logs[0]);
printf("%d\n", minOperations(logs, logsSize));
return 0;
}using System;
public class Solution {
public int MinOperations(string[] logs) {
int depth = 0;
foreach (string log in logs) {
if (log == "../") {
if (depth > 0) depth--;
} else if (log != "./") {
depth++;
}
}
return depth;
}
public static void Main(string[] args) {
Solution solution = new Solution();
string[] logs = {"d1/", "d2/", "../", "d21/", "./"};
Console.WriteLine(solution.MinOperations(logs));
}
}The Python code uses straightforward logic to iterate over log entries, adjusting depth based on each entry type. This results in a minimal and efficient solution.
Time Complexity: O(n).
Space Complexity: O(1).
Approach 2: Using Stack for Folder Simulation
This approach simulates navigating through folders using a stack. The stack keeps track of folder paths:
- For "x/", push the folder onto the stack.
- For "../", pop from the stack unless it's empty (indicating the root).
- For "./", do nothing, as it indicates staying in the same directory.
The stack's size at the end represents the current depth, which is the number of operations needed to return to the main folder.
def min_operations(logs):
stack = []
for log in logs:
if log == "../":
if stack:
stack.pop()
elif log != "./":
stack.append(log)
return len(stack)
logs = ["d1/", "d2/", "../", "d21/", "./"]
print(min_operations(logs))import java.util.Stack;
public class Solution {
public int minOperations(String[] logs) {
Stack<String> stack = new Stack<>();
for (String log : logs) {
if (log.equals("../")) {
if (!stack.isEmpty()) stack.pop();
} else if (!log.equals("./")) {
stack.push(log);
}
}
return stack.size();
}
public static void main(String[] args) {
Solution solution = new Solution();
String[] logs = {"d1/", "d2/", "../", "d21/", "./"};
System.out.println(solution.minOperations(logs));
}
}#include <vector>
#include <string>
#include <iostream>
using namespace std;
int minOperations(vector<string>& logs) {
vector<string> stack;
for (const auto& log : logs) {
if (log == "../") {
if (!stack.empty()) stack.pop_back();
} else if (log != "./") {
stack.push_back(log);
}
}
return stack.size();
}
int main() {
vector<string> logs = {"d1/", "d2/", "../", "d21/", "./"};
cout << minOperations(logs) << endl;
return 0;
}function minOperations(logs) {
const stack = [];
for (const log of logs) {
if (log === "../") {
if (stack.length > 0) stack.pop();
} else if (log !== "./") {
stack.push(log);
}
}
return stack.length;
}
const logs = ["d1/", "d2/", "../", "d21/", "./"];
console.log(minOperations(logs));#include <stdio.h>
#include <string.h>
int minOperations(char **logs, int logsSize) {
int stackDepth = 0;
for (int i = 0; i < logsSize; i++) {
if (strcmp(logs[i], "../") == 0) {
if (stackDepth > 0) stackDepth--;
} else if (strcmp(logs[i], "./") == 0) {
continue;
} else {
stackDepth++;
}
}
return stackDepth;
}
int main() {
char *logs[] = {"d1/", "d2/", "../", "d21/", "./"};
int logsSize = 5;
printf("%d\n", minOperations(logs, logsSize));
return 0;
}using System;
using System.Collections.Generic;
public class Solution {
public int MinOperations(string[] logs) {
Stack<string> stack = new Stack<string>();
foreach (string log in logs) {
if (log == "../") {
if (stack.Count > 0) stack.Pop();
} else if (log != "./") {
stack.Push(log);
}
}
return stack.Count;
}
public static void Main(string[] args) {
Solution solution = new Solution();
string[] logs = {"d1/", "d2/", "../", "d21/", "./"};
Console.WriteLine(solution.MinOperations(logs));
}
}The Python function leverages a list as a stack to model navigation through folder structures, effectively performing operations mimicking push and pop actions.
Time Complexity: O(n).
Space Complexity: O(n) because of the stack/list.
Approach 3: Default Approach
function minOperations(logs: string[]): number {
let ans = 0;
for (const x of logs) {
if (x === '../') {
ans && ans--;
} else if (x !== './') {
ans++;
}
}
return ans;
}func minOperations(logs []string) int {
ans := 0
for _, v := range logs {
if v == "../" {
if ans > 0 {
ans--
}
} else if v[0] != '.' {
ans++
}
}
return ans
}impl Solution {
pub fn min_operations(logs: Vec<String>) -> i32 {
let mut depth = 0;
for log in logs.iter() {
if log == "../" {
depth = (0).max(depth - 1);
} else if log != "./" {
depth += 1;
}
}
depth
}
}Complexity comparison
| Approach | Complexity |
|---|---|
| Using Depth Counter | Time Complexity: O(n). |
| Using Stack for Folder Simulation | Time Complexity: O(n). |
| Default Approach | – |
Complexity analysis
| Approach | Time | Space | When to Use |
|---|---|---|---|
| Depth Counter | O(n) | O(1) | Best choice when only folder depth matters and memory should remain minimal |
| Stack Simulation | O(n) | O(n) | Useful when explicitly modeling directory navigation or when folder names must be tracked |
Frequently asked questions
Is Crawler Log Folder easy or hard?
Crawler Log Folder is classified as an Easy problem on LeetCode with an acceptance rate above 70%. The challenge focuses on correctly interpreting directory navigation commands and implementing a simple simulation using counters or stacks.
Crawler Log Folder Python/Java solution
Both Python and Java implementations typically follow the depth counter approach. Loop through the logs, update an integer depth variable for each command, and return the final depth. The algorithm runs in O(n) time and requires constant extra space.
How to solve Crawler Log Folder in O(n)?
Iterate through the log array once and maintain a depth variable. Increment depth for folder entries like "x/", decrement it for "../" if depth is greater than zero, and ignore "./". After processing all logs, the depth value equals the minimum operations required to return to the root.
What is the best approach for Crawler Log Folder?
The depth counter approach is the most efficient solution. Track the current directory depth with a single integer while iterating through the logs. Increase depth when entering a folder, decrease it when encountering "../" (if depth > 0), and ignore "./". This runs in O(n) time and O(1) space.
Is Crawler Log Folder asked at Google/Amazon/Meta?
Crawler Log Folder is categorized as an easy array and string simulation problem and appears in interview preparation lists for companies such as Amazon and Google. It is commonly used to test basic simulation logic and familiarity with stack-like behavior.
What data structure is used in Crawler Log Folder?
Two main approaches exist. The optimal solution uses a simple integer counter to track folder depth. Another approach uses a stack to simulate directory navigation, pushing folder names and popping when moving up a directory.
What is the time complexity of Crawler Log Folder?
The optimal solution runs in O(n) time where n is the number of log entries. Each log command is processed once with constant work. The depth counter method uses O(1) space, while the stack simulation approach may use O(n) space in the worst case.
