题目链接:https://leetcode.com/problems/longest-absolute-file-path/
题目:
Suppose we abstract our file system by a string in the following manner:
"dir\n\tsubdir1\n\tsubdir2\n\t\tfile.ext"
dir subdir1 subdir2 file.ext
dir
contains an empty sub-directory subdir1
and a sub-directory subdir2
containing a file file.ext
."dir\n\tsubdir1\n\t\tfile1.ext\n\t\tsubsubdir1\n\tsubdir2\n\t\tsubsubdir2\n\t\t\tfile2.ext"
dir subdir1 file1.ext subsubdir1 subdir2 subsubdir2 file2.ext
dir
contains two sub-directories subdir1
and subdir2
. subdir1
contains a file file1.ext
and an empty second-level sub-directory subsubdir1
. subdir2
contains a second-level sub-directory subsubdir2
containing a file file2.ext
."dir/subdir2/subsubdir2/file2.ext"
, and its length is 32
0
.
Note:
- The name of a file contains at least a
.
- The name of a directory or sub-directory will not contain a
.
- .
O(n)
where n
a/aa/aaa/file1.txt
is not the longest file path, if there is another path aaaaaaaaaaaaaaaaaaaaa/sth.png
.
思路:
思路比较简单,用一个可变数组维护一个从根目录到当前目录的绝对路径的长度。。。好绕口。。= =说出来自己都不懂。。
要注意绝对路径结尾必须包含一个文件才有算有效,且绝对路径需要一个长度为1的分隔符 \ 。
举个栗子:dir \n\tdir1 \n\tdir20 \n\t\tfile.ext 意思是:dir目录下有两文件夹dir1和dir20,其中dir20目录下有文件file.ext。
dir\dir20\ tfile.ext 最长绝对路径为17+2=19。
算法:
public int lengthLongestPath(String input) {
List<Integer> lenOfLevel = new ArrayList<Integer>();
int max = 0, level = 0, preIdx = 0;
input = input + '\n';//使得每个路径token后都接一个\n,便于统一处理
boolean isFile = false;
for (int i = 0; i < input.length(); i++) {
if (input.charAt(i) == '.') {// 当前路径是否包含文件
isFile = true;
}
if (input.charAt(i) != '\n') // 换一行
continue;
int tokenLen = i - preIdx + 1;//一个目录token的长度
int tmp = tokenLen;
if (level - 1 >= 0) {// 如果当前路径有上一层
tmp += lenOfLevel.get(level - 1);// 则绝对路径长度需要加上上一层绝对路径长度
}
if (level <= lenOfLevel.size() - 1)// 当前路径有比它更深层的路径
lenOfLevel.set(level, tmp);
else
lenOfLevel.add(tmp);// 当前路径是目前遇到的最深的路径
if (isFile) {// 当前绝对路径包含文件,则是一条可以计算长度的有效路径
max = Math.max(max, tmp);// 更新max
isFile = false;
}
int nIdx = i;// 更新待计算token的level
i++;
while (i < input.length() && input.charAt(i) == '\t') {
i++;
}
level = i - nIdx - 1;
preIdx = i;// 更新待计算token的起始位置
}
return max - 1 >= 0 ? max - 1 : 0;
}