题目地址:
https://leetcode.com/problems/longest-absolute-file-path/
给定一个文件系统,以字符串
s
s
s的形式给出,如下图所示:
s
s
s会按照上图所示一行一行地拼接起来,遇到'\t'
则说明深度加深
1
1
1层。对于连续的不含'\t'
和'\n'
的一段,其代表一个文件夹名或者文件名,如果其含'.'
则视为文件,否则视为文件夹。问对于所有的文件,路径名最长的那个文件的路径名长多少。路径名含文件名,并且在文件夹名之间以及文件名与文件夹名之间有一个'/'
。
可以用栈,栈内存放路径上每个文件(夹)的名称长度。每个文件(夹)一定是开头若干个'\t'
,然后接着是名字,接着是'\n'
,其中'\t'
的个数代表其深度(最外层深度视为
0
0
0)。所以可以先解析出'\t'
的个数,如果当前栈的size大于了这个深度,则pop掉栈顶直到size等于深度(类似于DFS一棵树的时候做回溯),然后解析出文件(夹)名称长度,接着将这个名字长度入栈,再看一下这个名字是文件还是文件夹,如果是文件,则可以更新答案。代码如下:
class Solution {
public:
int lengthLongestPath(string s) {
stack<int> stk;
int res = 0;
// 循环不变量是,每次循环开始的时候都有一个以0或多个'\t'开头,
// 以'\n'或结尾为末尾的前缀作为文件(夹)
for (int i = 0, len = 0; i < s.size(); i++) {
int dep = 0;
// 求一下接下来要解析的文件(夹)的深度
while (i < s.size() && s[i] == '\t') dep++, i++;
// 把超出深度的文件(夹)弹掉
while (stk.size() > dep) len -= stk.top(), stk.pop();
// 解析出文件(夹)名,并记录其是文件还是文件夹
int j = i;
bool has_dot = false;
while (j < s.size() && s[j] != '\n') {
if (s[j] == '.') has_dot = true;
j++;
}
len += j - i;
stk.push(j - i);
// stk.size() - 1是'/'的个数
if (has_dot) res = max(res, len + (int)stk.size() - 1);
i = j;
}
return res;
}
};
时间复杂度 O ( l s ) O(l_s) O(ls),空间 O ( d ) O(d) O(d), d d d为最深的文件(夹)的深度。