栈与队列中等1 种解法
#71简化路径
把 Unix 风格绝对路径转换为规范路径。
#字符串#栈
原题
给你一个字符串 path ,表示指向某一文件或目录的 Unix 风格 绝对路径 (以 '/' 开头),请你将其转化为 更加简洁的规范路径。
在 Unix 风格的文件系统中规则如下:
- 一个点
'.'表示当前目录本身。 - 此外,两个点
'..'表示将目录切换到上一级(指向父目录)。 - 任意多个连续的斜杠(即,
'//'或'///')都被视为单个斜杠'/'。 - 任何其他格式的点(例如,
'...'或'....')均被视为有效的文件/目录名称。
返回的 简化路径 必须遵循下述格式:
- 始终以斜杠
'/'开头。 - 两个目录名之间必须只有一个斜杠
'/'。 - 最后一个目录名(如果存在)不能 以
'/'结尾。 - 此外,路径仅包含从根目录到目标文件或目录的路径上的目录(即,不含
'.'或'..')。
返回简化后得到的 规范路径 。
示例 1:
输入:path = "/home/"
输出:"/home"
解释:
应删除尾随斜杠。
示例 2:
输入:path = "/home//foo/"
输出:"/home/foo"
解释:
多个连续的斜杠被单个斜杠替换。
示例 3:
输入:path = "/home/user/Documents/../Pictures"
输出:"/home/user/Pictures"
解释:
两个点 ".." 表示上一级目录(父目录)。
示例 4:
输入:path = "/../"
输出:"/"
解释:
不可能从根目录上升一级目录。
示例 5:
输入:path = "/.../a/../b/c/../d/./"
输出:"/.../b/d"
解释:
"..." 在这个问题中是一个合法的目录名。
提示:
1 <= path.length <= 3000path由英文字母,数字,'.','/'或'_'组成。path是一个有效的 Unix 风格绝对路径。
解题主线
- 按斜杠切分后,普通目录入栈,.. 弹出上级,空段与 . 忽略。
解法 1:目录栈
扫描路径段并维护规范目录序列,最后从栈底到栈顶用斜杠连接。
-
时间复杂度: O(n)
-
空间复杂度: O(n)
import java.util.ArrayDeque;
import java.util.Deque;
final class Solution {
public String simplifyPath(String path) {
// 双端队列从队尾维护当前规范路径的目录栈
Deque<String> directories = new ArrayDeque<>();
for (String part : path.split("/")) {
// 连续斜杠产生的空段和当前目录标记都不改变路径
if (part.isEmpty() || part.equals(".")) continue;
if (part.equals("..")) {
// 根目录没有父级,空栈时忽略继续向上的请求
if (!directories.isEmpty()) directories.removeLast();
} else {
directories.addLast(part);
}
}
if (directories.isEmpty()) return "/";
return "/" + String.join("/", directories);
}
}边界与易错点
- 根目录上的 .. 不应继续向上,也不应作为普通目录入栈。
- 名称如 ... 是普通目录,只有恰好为 . 或 .. 才有特殊含义。
- ArrayDeque 比遗留 Stack 更适合作为栈。
整理来源
由旧仓库源码复核、去重并整理;展示代码已按 Java 21 语义修正明显问题。
medium/Q071_simplifyPath.java