这种文件系统的题目很大程度上都是依赖于Stack来解决问题的。这一题也是,你用Stack来表示现在是第几级别的子文件夹。这一题有一个隐含条件就是子文件夹的级数的增加是一级级递增的(减少并不是)。如果我们用隔行符(\n)作为字符分割的字符的话。我们得到的每一个子字符串就是一条path记录。因为是一级级递增的,所以你不会存在现在这个path是\t\t\dirA,然后下一个\t\t\t\t\dirB或者\t\t\t\t\t\file.file的情况,因为这样的话你会不知道中间的文件夹名字是啥。所以做法其实很直白。先把整个字符串用隔行符\n分成一个个path。然后每个path进行分析。首先找有多少个/t,表示前面有多少个文件夹的级数。接下来会有两种情况:1.往前进一级。 譬如 上一个是\t\t\dirA,你这里应该就是\t\t\t\filename.file之类的。2.或者,往回退到某一级。譬如你之前是\t\t\t\filename.file,这一次可能就是\t\dirB这样。如果是这种情况,就表示之前经历过比他级数更多的子文件夹名已经不会再有效了,直接从stack里面pop出来就可以了。所以在\t\dirB这个case,就pop到stack里面只剩下一个元素,然后根据当前的path的长度结合stack里的数据得到path的整体长度,然后把这个path的长度push到stack里面作为之后的级数的参考。在遍历所有path的过程里保留一个最大长度即可。要注意的是,/t其实不是两个字符而是一个,你用System.out.println("/t")的时候只会出现一个tab长度的空的间隔,就和你按了一下tab是一样的,所以在找多少个/t的时候要注意。
public int lengthLongestPath(String input) {
Stack<Integer> dirStack = new Stack<>();
String[] paths = input.split("\n");
int maxLen = 0;
for (String path : paths) {
// Getting how many \t
int lvlOfTabs = path.lastIndexOf("\t") + 1;
// setting stack to whatever level of sub directory it locates
while (lvlOfTabs < dirStack.size()) {
dirStack.pop();
}
// whole path's length - how many \t + subdirectory length + 1(one more slash \)
int curLen = path.length() - lvlOfTabs + (dirStack.isEmpty() ? 0 : dirStack.peek()) + 1;
// If path contains a ., then it will be a file.
if (path.contains(".")) {
maxLen = Math.max(maxLen, curLen - 1);
}
dirStack.push(curLen);
}
return maxLen;
}
用所谓的arraystack的话可以再稍微精简一点。
public int lengthLongestPath(String input) {
String[] paths = input.split("\n");
int[] pathsLens = new int[paths.length + 1];
int maxLen = 0;
for (String path : paths) {
int lvlOfTabs = path.lastIndexOf("\t") + 1;
int curLen = path.length() - lvlOfTabs + pathsLens[lvlOfTabs] + 1;
if (path.contains(".")) {
maxLen = Math.max(maxLen, curLen - 1);
}
pathsLens[lvlOfTabs + 1] = curLen;
}
return maxLen;
}