题目:
题解:模拟 + 哈希表
代码:
import java.util.HashMap;
import java.util.Map;
/**
* @program: LeetCode
* @author: zhangyx
* @create: 2022-05-22 17:56
**/
public class code388 {
public static int lengthLongestPath(String input) {
String s = input;
Map<Integer, String> map = new HashMap<>();
int len = s.length();
String ans = null;
for (int i = 0; i < len; ) {
int level = 0; // 用level来记录目录级数
// 用while循环跳过制表符, 并增加层数
while (i < len && s.charAt(i) == '\t' && (++level >= 0)) {
i++; // 这里是统计目录级别,只有当chars[i]为'\t'时后边的++level才执行
}
int j = i; // i与j当前都在目录名或文件名的首位
boolean isDirectory = true; // 判断是不是目录, 默认它是一个目录
// 把文件和目录分开来判断
// 最后一个一定要是文件, 前面一定要是目录
// 如果有点(".")的话, 说明不是目录
// 当前文件或者目录(不换行的话) j计算当前深度的文件或目录的长度
while (j < len && s.charAt(j) != '\n') { // 如果j所在字符不为'\n'
if (s.charAt(j) == '.') {
isDirectory = false; // 判断是否有“.”,有“.”则为文件名,修改isDirectory,同时j后移
}
j++;
}
String cur = s.substring(i, j); // cur为当前的长度, 当前j所在位置为'\n',则目录名或文件名的长度为j-i
// getOrDefault() 方法获取指定 key 对应对 value,如果找不到 key ,则返回设置的默认值。
// prev 代表的是上一层的之前的长度, 先通过level找到数组对应的位置
String prev = map.getOrDefault(level - 1, null); // 找出哈希表中当前这一级目录的上一级目录的长度
// 因为i, j会比实际大1,所以长度正确,加一加的是斜杆的长度
String path = null;
if (prev == null) {
path = cur;
} else {
path = prev + "/" + cur; // 计算出长度
}
if (isDirectory) {
map.put(level, path); // 如果是目录的话,不计算长度,长度算上一份文件的长度 // 如果是目录则更新当前等级的目录长度
} else if (ans == null || path.length() > ans.length()) {
ans = path; // 如果是文件的话,满足条件就更新长度 // 如果不是说明找到了文件,更新文件长度ans
}
// j在'\n',将i移动到j的下一位。下一位可能是'\t',也可能是目录名或文件名,下次循环时将会考虑到这些情况
i = j + 1; // j+1以后, 跳过了\n 换行符, 进行\t的判断
}
if (ans == null) {
return 0;
} else {
return ans.length();
}
}
public static void main(String[] args) {
String s = "dir\n\tsubdir1\n\tsubdir2\n\t\tfile.ext";
int res = lengthLongestPath(s);
System.out.println(res);
}
}