这是我参与2022首次更文挑战的第25天,活动详情查看:2022首次更文挑战
leetcode 简化路径
给你一个字符串 path ,表示指向某一文件或目录的 Unix 风格 绝对路径 (以 '/' 开头),请你将其转化为更加简洁的规范路径。
在 Unix 风格的文件系统中,一个点(.)表示当前目录本身;此外,两个点 (..) 表示将目录切换到上一级(指向父目录);两者都可以是复杂相对路径的组成部分。任意多个连续的斜杠(即,'//')都被视为单个斜杠 '/' 。 对于此问题,任何其他格式的点(例如,'...')均被视为文件/目录名称。
请注意,返回的 规范路径 必须遵循下述格式:
始终以斜杠 '/' 开头。 两个目录名之间必须只有一个斜杠 '/' 。 最后一个目录名(如果存在)不能 以 '/' 结尾。 此外,路径仅包含从根目录到目标文件或目录的路径上的目录(即,不含 '.' 或 '..')。 返回简化后得到的 规范路径 。
示例 1:
输入:path = "/home/"
输出:"/home"
解释:注意,最后一个目录名后面没有斜杠。
示例 2:
输入:path = "/../"
输出:"/"
解释:从根目录向上一级是不可行的,因为根目录是你可以到达的最高级。
示例 3:
输入:path = "/home//foo/"
输出:"/home/foo"
解释:在规范路径中,多个连续斜杠需要用一个斜杠替换。
解题:可以利用栈来完成。目录之间是用一个斜杠/来分隔的,所以可以先将给定字符串path根据/符号来分段组成一个数组paths,然后我们分析paths数组的元素。path字符串是由英文字母,数字,'.','/' 或 ''组成,所以paths数组元素也都是英文字母,数字,'.','',或 '' 组成,因为是根据'/'分割所以,如果连续出现'/'那分割的时候就会用空字符串元素,那么对于空字符串''元素或者'.'一个点的元素就可以忽略,因为任意多个连续的斜杠'///'需要被视为单个斜杠'/',而单个点'.'的元素是表示当前目录。对于两个点'..'的元素代表要将目录切换到上一级,那具体的可以将paths数组的元素分为3类,第一类为空字符串''和单个点'.';第二类为两个点'..'代表切换到上一级;第三类就是其余字符的组合代表目录名。对此我们可以使用栈可以比较方便的处理,遍历paths数组当遇到空字符串''或者单个点'.'这些元素的时候就跳过本次循环,当遇到第三类元素时为一个目录名,就将该元素添加到栈里面,当遇到第二类元素要切换回上一级目录,在栈元素不为空的情况下,就取出一个栈元素来实现回到上级目录,如此反复操作直到遍历完paths数组元素,然后判断如果栈是空的就直接返回根目录'/',否则就循环从栈底取出元素拼接到斜杆'/'后面,最后返回即可。
class Solution {
public String simplifyPath(String path) {
Deque<String> stack = new ArrayDeque<String>();
String[] paths = path.split("/");
for (String str : paths) {
if (str.length() == 0 || ".".equals(str)) {
continue;
}
if ("..".equals(str)) {
if (!stack.isEmpty()) {
stack.pollLast();
}
continue;
}
stack.offerLast(str);
}
if (stack.isEmpty()) {
return "/";
}
StringBuilder res = new StringBuilder();
while (!stack.isEmpty()) {
res.append('/').append(stack.pollFirst());
}
return res.toString();
}
}