leetcode388 - Longest Absolute File Path - medium
Suppose we abstract our file system by a string in the following manner:
The string "dir\n\tsubdir1\n\tsubdir2\n\t\tfile.ext" represents:
dir
subdir1
subdir2
file.ext
The directory dir contains an empty sub-directory subdir1 and a sub-directory subdir2 containing a file file.ext.
The string "dir\n\tsubdir1\n\t\tfile1.ext\n\t\tsubsubdir1\n\tsubdir2\n\t\tsubsubdir2\n\t\t\tfile2.ext" represents:
dir
subdir1
file1.ext
subsubdir1
subdir2
subsubdir2
file2.ext
The directory 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.
We are interested in finding the longest (number of characters) absolute path to a file within our file system. For example, in the second example above, the longest absolute path is "dir/subdir2/subsubdir2/file2.ext", and its length is 32 (not including the double quotes).
Given a string representing the file system in the above format, return the length of the longest absolute path to file in the abstracted file system. If there is no file in the system, return 0.
Note:
* The name of a file contains at least a . and an extension.
* The name of a directory or sub-directory will not contain a ..
Time complexity required: O(n) where n is the size of the input string.
Notice that a/aa/aaa/file1.txt is not the longest file path, if there is another path aaaaaaaaaaaaaaaaaaaaa/sth.png.
模拟法。Stack<String>或者int[] levelLen
题目感受:
每出现\n就表示新一行,每一行里最前面顶了几个\t表示缩进了多少也就是第几级。
一行行看下来,根据级数变化的操作,有一种stack的感觉。1.如果增级,入栈,目录长度+我;2.如果平级,吐出之前和自己平级的那一个把自己放进去,目录长度-前+我;3.如果减级,吐出之前好几级直到吐到栈里只有我的前一级,再把我入栈,目录长度根据吞吐调整。
法1:真Stack。
具体对每一行:
1.while循环对比现在这行的等级和栈顶等级,只要栈顶等级更高或者和我平级就都吐掉,同时更新length.
2.把当前这行加入栈里,更新length。
3.如果当前这行有文件,打一下擂台确认最大长度。
细节:
1.Stack结构为Stack<String>而不可Stack<Integer>,因为你要记录的信息有当前这行的长度和这行的等级两个数据,那你要么需要两个stack要么就直接存string之后又需求再去求。
2.把原始数组先用split函数拆成一行一行简单很多!
3.计算等级也就是统计有多少个’\t’,最简单的方法是直接line.lastIndexOf("\t") + 1;
4.string的split()还有contains()都要求输入参数为””而不可以是’',尽量这种题目输入单个字符也用”"吧。目前就知道sb是可以直接append ‘’的。
5.'\n', '\t'是一个字符而不是两个
6.更新最后返回的长度的时候要用s.length() - level(s) + 1; 减掉前面的tab,+1是因为题目要求的长度要计算加入层级分隔符’/‘的长度。另外在打擂台的时候又要用count - 1是因为path格式的最后是不带’/‘的。
法1:
class Solution { public int lengthLongestPath(String input) { // P1: 不可Stack<Integer>只存长度,你还需要记忆栈顶是第几层的,所以你要么两个stack要么stack<String>存整个。 Stack<String> stack = new Stack<>(); // P2: '\n', '\t'是一个字符而不是两个 // P3: 先split成一行一行简单很多! // P4 string.split()和string.contains()里面只能填string不能char!一般还是都用""吧就sb.append可以用char String[] strs = input.split("\n"); int ans = 0; int count = 0; for (String s : strs) { while (!stack.isEmpty() && level(s) <= level(stack.peek())) { String top = stack.pop(); count -= (top.length() - level(top) + 1); } stack.push(s); // P5: +1是为了path里的'/', 对比时的-1是为了path最后没有'/' count += s.length() - level(s) + 1; if (s.contains(".")) { ans = Math.max(ans, count - 1); } } return ans; } private int level(String s) { int i = 0, sum = 0; while (s.charAt(i++) == '\t') { sum++; } return sum; } }
法2:
class Solution { public int lengthLongestPath(String input) { int[] lens = new int[input.length()]; int ans = 0; String[] lines = input.split("\n"); for (String line : lines) { int level = line.lastIndexOf("\t") + 1; int len = line.length() - level + 1; int prevLen = level == 0 ? 0 : lens[level - 1]; if (line.contains(".")) { ans = Math.max(ans, prevLen + len - 1); } else { lens[level] = prevLen + len; } } return ans; } }