题目描述
以 Unix 风格给出一个文件的绝对路径,你需要简化它。或者换句话说,将其转换为规范路径。
在 Unix 风格的文件系统中,一个点(.)表示当前目录本身;此外,两个点 (..) 表示将目录切换到上一级(指向父目录);两者都可以是复杂相对路径的组成部分。更多信息请参阅:Linux / Unix中的绝对路径 vs 相对路径
请注意,返回的规范路径必须始终以斜杠 / 开头,并且两个目录名之间必须只有一个斜杠 /。最后一个目录名(如果存在)不能以 / 结尾。此外,规范路径必须是表示绝对路径的最短字符串。
71. 简化路径
解法1 栈
核心是使用String里的split函数将路径按 / 分割,连续的 / 如 // 路径为"",获得路径后如果等于..将路径出栈,如果路径不是""和.,入栈。最后将栈中的路径名,用 / 组合起来返回结果。
class Solution {
public static String simplifyPath(String path) {
Deque<String> stack = new LinkedList<>();
// item为路径名
for (String item : path.split("/")) {
// item为..,将栈顶的路径出栈
if (item.equals("..")) {
if (!stack.isEmpty()) stack.pop();
} else if (!item.isEmpty() && !item.equals(".")) {
// item为空,说明item是在两个 / 中间得到的,为一个 . 忽略
stack.push(item);
}
}
String res = "";
// 各个路径名组合
for (String d : stack) res = "/" + d + res;
return res.isEmpty() ? "/" : res;
}
}
解法2 数组
题解里看到的代码。如果使用栈并且不适用split()函数,入栈操作和出栈操作一个字符串一个字符串判断,...的情况会难处理,使用数组来模拟栈是一个常规思路。
public static String simplifyPath(String path) {
// 设置chs数组存放字符串中的字符
// 在执行中chs数组会被更新
path += '/';
char[] chs = path.toCharArray();
int top = -1;
for (char c : chs) {
// 前两个if语句保证将多余的 / 去除
if (top == -1 || c != '/') {
chs[++top] = c;
continue;
}
if (chs[top] == '/') {
continue;
}
// /. 形式将.去除
if (chs[top] == '.' && chs[top - 1] == '/') {
top--;
continue;
}
// /.. 形式去除上一级目录
if (chs[top] == '.' && chs[top - 1] == '.' && chs[top - 2] == '/') {
top -= 2;
// 循环将上一级目录去除
while (top > 0 && chs[--top] != '/') ;
continue;
}
// 其它情况将字符覆盖chs数组相应位置
chs[++top] = c;
}
// 如果最后一个字符是 / ,移除
if (top > 0 && chs[top] == '/') top--;
return new String(chs, 0, top + 1);
}
总结
三个点这种情况一开始没有想到,直接用栈处理对付...这样的有点困难。