 
  
 
题目描述
每当用户执行变更文件夹操作时,LeetCode 文件系统都会保存一条日志记录。
下面给出对变更操作的说明:
    - "../":移动到当前文件夹的父文件夹。如果已经在主文件夹下,则 继续停留在当前文件夹 。
- "./":继续停留在当前文件夹。
- "x/":移动到名为- x的子文件夹中。题目数据 保证总是存在文件夹- x。
给你一个字符串列表 logs ,其中 logs[i] 是用户在 ith 步执行的操作。
文件系统启动时位于主文件夹,然后执行 logs 中的操作。
执行完所有变更文件夹操作后,请你找出 返回主文件夹所需的最小步数 。
 
示例 1:

输入:logs = ["d1/","d2/","../","d21/","./"]
输出:2
解释:执行 "../" 操作变更文件夹 2 次,即可回到主文件夹
示例 2:

输入:logs = ["d1/","d2/","./","d3/","../","d31/"]
输出:3
示例 3:
输入:logs = ["d1/","../","../","../"]
输出:0
 
提示:
    - 1 <= logs.length <= 103
- 2 <= logs[i].length <= 10
- logs[i]包含小写英文字母,数字,- '.'和- '/'
- logs[i]符合语句中描述的格式
- 文件夹名称由小写英文字母和数字组成
解法
方法一:模拟
直接模拟,记录深度的变化即可。
时间复杂度 \(O(n)\),空间复杂度 \(O(1)\)。其中 \(n\) 为 logs 的长度。
|  | class Solution:
    def minOperations(self, logs: List[str]) -> int:
        ans = 0
        for v in logs:
            if v == "../":
                ans = max(0, ans - 1)
            elif v[0] != ".":
                ans += 1
        return ans
 | 
 
|  1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13 | class Solution {
    public int minOperations(String[] logs) {
        int ans = 0;
        for (var v : logs) {
            if ("../".equals(v)) {
                ans = Math.max(0, ans - 1);
            } else if (v.charAt(0) != '.') {
                ++ans;
            }
        }
        return ans;
    }
}
 | 
 
|  1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14 | class Solution {
public:
    int minOperations(vector<string>& logs) {
        int ans = 0;
        for (auto& v : logs) {
            if (v == "../") {
                ans = max(0, ans - 1);
            } else if (v[0] != '.') {
                ++ans;
            }
        }
        return ans;
    }
};
 | 
 
|  1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13 | func minOperations(logs []string) int {
    ans := 0
    for _, v := range logs {
        if v == "../" {
            if ans > 0 {
                ans--
            }
        } else if v[0] != '.' {
            ans++
        }
    }
    return ans
}
 | 
 
|  | function minOperations(logs: string[]): number {
    let ans = 0;
    for (const x of logs) {
        if (x === '../') {
            ans && ans--;
        } else if (x !== './') {
            ans++;
        }
    }
    return ans;
}
 | 
 
|  | function minOperations(logs) {
    let ans = 0;
    for (const x of logs) {
        if (x === '../') {
            ans && ans--;
        } else if (x !== './') {
            ans++;
        }
    }
    return ans;
}
 | 
 
|  1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13 | 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
    }
}
 | 
 
|  1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14 | #define max(a, b) (((a) > (b)) ? (a) : (b))
int minOperations(char** logs, int logsSize) {
    int depth = 0;
    for (int i = 0; i < logsSize; i++) {
        char* log = logs[i];
        if (!strcmp(log, "../")) {
            depth = max(0, depth - 1);
        } else if (strcmp(log, "./")) {
            depth++;
        }
    }
    return depth;
}
 |