LeetCode 1598: Crawler Log Folder (Depth Counter Simulation)
LeetCode 1598StringSimulationStackToday we solve LeetCode 1598 - Crawler Log Folder.
Source: https://leetcode.com/problems/crawler-log-folder/
English
Problem Summary
Given folder change logs, compute the minimum number of operations needed to return to the main folder. Logs can be:
- "../": move to parent (unless already at root)
- "./": stay in current folder
- "x/": move into child folder x
Key Insight
We do not need actual folder names. We only need current depth from root:
- "x/" increases depth by 1
- "../" decreases depth by 1 only when depth > 0
- "./" keeps depth unchanged
Final depth is exactly the answer.
Algorithm
1) Initialize depth = 0.
2) Scan each log:
- if "../", set depth = max(0, depth - 1)
- else if "./", do nothing
- else, depth++
3) Return depth.
Complexity Analysis
Time: O(n).
Space: O(1).
Common Pitfalls
- Letting depth go negative when handling "../" at root.
- Building a real stack of names when only depth is required.
- Misclassifying "./" as entering a child folder.
Reference Implementations (Java / Go / C++ / Python / JavaScript)
class Solution {
public int minOperations(String[] logs) {
int depth = 0;
for (String log : logs) {
if ("../".equals(log)) {
if (depth > 0) depth--;
} else if ("./".equals(log)) {
// stay
} else {
depth++;
}
}
return depth;
}
}func minOperations(logs []string) int {
depth := 0
for _, log := range logs {
if log == "../" {
if depth > 0 {
depth--
}
} else if log == "./" {
// stay
} else {
depth++
}
}
return depth
}class Solution {
public:
int minOperations(vector<string>& logs) {
int depth = 0;
for (const string& log : logs) {
if (log == "../") {
if (depth > 0) depth--;
} else if (log == "./") {
// stay
} else {
depth++;
}
}
return depth;
}
};class Solution:
def minOperations(self, logs: list[str]) -> int:
depth = 0
for log in logs:
if log == "../":
if depth > 0:
depth -= 1
elif log == "./":
pass
else:
depth += 1
return depthvar minOperations = function(logs) {
let depth = 0;
for (const log of logs) {
if (log === "../") {
if (depth > 0) depth--;
} else if (log === "./") {
// stay
} else {
depth++;
}
}
return depth;
};中文
题目概述
给定一组文件夹操作日志,计算回到主文件夹(根目录)最少还需要几步。日志类型如下:
- "../":返回父目录(但在根目录时不能再往上)
- "./":停留在当前目录
- "x/":进入名为 x 的子目录
核心思路
不需要维护真实路径,只要维护“当前深度 depth”:
- 进入子目录:depth += 1
- 返回父目录:depth = max(0, depth - 1)
- 原地不动:depth 不变
最终 depth 就是答案。
算法步骤
1)初始化 depth = 0。
2)遍历每条日志:
- 若为 "../",且 depth > 0 时减 1
- 若为 "./",不处理
- 否则为进入子目录,depth++
3)返回 depth。
复杂度分析
时间复杂度:O(n)。
空间复杂度:O(1)。
常见陷阱
- 在根目录处理 "../" 时让深度变成负数。
- 误以为必须真的用栈保存目录名。
- 把 "./" 误判成进入子目录。
多语言参考实现(Java / Go / C++ / Python / JavaScript)
class Solution {
public int minOperations(String[] logs) {
int depth = 0;
for (String log : logs) {
if ("../".equals(log)) {
if (depth > 0) depth--;
} else if ("./".equals(log)) {
// stay
} else {
depth++;
}
}
return depth;
}
}func minOperations(logs []string) int {
depth := 0
for _, log := range logs {
if log == "../" {
if depth > 0 {
depth--
}
} else if log == "./" {
// stay
} else {
depth++
}
}
return depth
}class Solution {
public:
int minOperations(vector<string>& logs) {
int depth = 0;
for (const string& log : logs) {
if (log == "../") {
if (depth > 0) depth--;
} else if (log == "./") {
// stay
} else {
depth++;
}
}
return depth;
}
};class Solution:
def minOperations(self, logs: list[str]) -> int:
depth = 0
for log in logs:
if log == "../":
if depth > 0:
depth -= 1
elif log == "./":
pass
else:
depth += 1
return depthvar minOperations = function(logs) {
let depth = 0;
for (const log of logs) {
if (log === "../") {
if (depth > 0) depth--;
} else if (log === "./") {
// stay
} else {
depth++;
}
}
return depth;
};
Comments