题目来源:LeetCode 388. 文件的最长绝对路径
问题抽象: 给定一个表示文件目录结构的字符串 input(由换行符 '\n'、制表符 '\t' 和字母组成),要求计算所有 文件绝对路径 的最大长度(包括目录名和文件名之间的分隔符 '/'),满足以下核心需求:
-
结构解析规则:
- 每行表示一个文件或目录,由换行符分隔;
- 行首制表符数量表示深度(根目录深度
0,无制表符); - 文件绝对路径为从根目录到文件的完整路径(如
"dir/subdir/file.ext")。
-
路径构建要求:
- 路径分隔符为
'/'(非系统相关); - 路径长度包括所有目录名、文件名和分隔符(不含制表符和换行符);
- 仅对文件(名称含
.和扩展名)计算路径长度。
- 路径分隔符为
-
计算约束:
- 时间复杂度 O(n)(
n为字符串长度),空间复杂度 O(d)(d为最大深度); - 使用 栈 维护当前路径:
- 栈存储各层路径累计长度;
- 每行解析:统计制表符数得深度,弹出栈顶直到栈深等于当前深度;
- 当前项长度 = 栈顶值(若栈非空)
+ 1(分隔符)+名称长度; - 若为文件,更新最大长度;若为目录,压栈当前长度。
- 时间复杂度 O(n)(
-
边界处理:
- 空字符串 → 返回
0; - 无文件 → 返回
0; - 特殊输入:
"dir\n\tsubdir1\n\tsubdir2\n\t\tfile.ext"→ 最长路径"dir/subdir2/file.ext"长度20;"a.txt"(单文件)→ 路径"a.txt"长度5;"a"(单目录)→ 无文件,返回0;"dir\n\tfile1.txt\n\tsubdir\n\t\tfile2.txt"→ 最长路径"dir/subdir/file2.txt"长度18;
- 深度递增约束:连续制表符(如
"\t\t"表示深度2)。
- 空字符串 → 返回
输入:字符串 input(长度 ≥0)。
输出:整数值(最长文件绝对路径长度,无文件时返回 0)。
解题思路
题目要求计算文件系统中文件绝对路径的最大长度。输入字符串使用\n表示换行,\t表示层级关系,包含扩展名(如.txt)的项被视为文件。
核心思路是使用一个数组模拟栈,记录每一层目录的累计路径长度(包括目录名和分隔符),遍历每一行:
- 计算层级:统计行首的
\t个数作为当前层级。 - 获取名称:移除行首的
\t后得到当前文件或目录的名称。 - 计算路径长度:
- 根目录(层级0):路径长度 = 名称长度。
- 非根目录:路径长度 = 上一层级累计长度 + 当前名称长度。
- 更新结果:
- 若是文件(名称含
.),更新最大路径长度。 - 若是目录,将
当前路径长度 + 1(加1是为下一级添加分隔符/)存入栈中,供下一层级使用。
- 若是文件(名称含
此方法时间复杂度为O(n),空间复杂度为O(n),n为输入行数。
代码实现(Java版)🔥点击下载源码
class Solution {
public int lengthLongestPath(String input) {
if (input == null || input.isEmpty()) {
return 0;
}
// 按换行符分割输入字符串
String[] lines = input.split("\n");
int n = lines.length;
// 栈数组:stack[i]存储第i层的最新路径长度(含结尾分隔符)
int[] stack = new int[n];
int maxLen = 0; // 记录最大文件路径长度
for (String line : lines) {
// 计算层级:统计行首的\t个数
int level = 0;
while (level < line.length() && line.charAt(level) == '\t') {
level++;
}
// 获取当前名称(移除行首\t)
String name = line.substring(level);
int nameLen = name.length();
// 计算当前完整路径长度
int curLen;
if (level == 0) {
curLen = nameLen; // 根目录
} else {
// 非根目录:父层级路径长度 + 当前名称长度
curLen = stack[level - 1] + nameLen;
}
// 判断是否为文件(名称包含.)
if (name.contains(".")) {
maxLen = Math.max(maxLen, curLen); // 更新最大长度
} else {
// 目录:存储当前路径长度+1(为下一级预留分隔符/)
if (level < n) {
stack[level] = curLen + 1;
}
}
}
return maxLen;
}
}
代码说明
- 输入处理:使用
split("\n")将输入分割成行数组。 - 层级计算:遍历行首字符统计
\t数量确定层级。 - 名称提取:通过
substring(level)移除行首\t获取纯净名称。 - 路径长度计算:
- 根目录(
level=0)路径长度等于名称长度。 - 非根目录路径长度 = 父层级栈值(
stack[level-1]) + 当前名称长度。
- 根目录(
- 文件判断:名称包含
.视为文件,更新maxLen。 - 目录处理:目录路径长度需加1(末尾分隔符
/)后存入栈,供子级使用。
提交详情(执行用时、内存消耗)

1079

被折叠的 条评论
为什么被折叠?



