欢迎关注我的公众号《小沈干货》,谢谢大家。
以 Unix 风格给出一个文件的绝对路径,你需要简化它。或者换句话说,将其转换为规范路径。
在 Unix 风格的文件系统中,一个点(.
)表示当前目录本身;此外,两个点 (..
) 表示将目录切换到上一级(指向父目录);两者都可以是复杂相对路径的组成部分。更多信息请参阅:Linux / Unix中的绝对路径 vs 相对路径
请注意,返回的规范路径必须始终以斜杠 /
开头,并且两个目录名之间必须只有一个斜杠 /
。最后一个目录名(如果存在)不能以 /
结尾。此外,规范路径必须是表示绝对路径的最短字符串。
示例 1:
输入:"/home/" 输出:"/home" 解释:注意,最后一个目录名后面没有斜杠。
示例 2:
输入:"/../" 输出:"/" 解释:从根目录向上一级是不可行的,因为根是你可以到达的最高级。
示例 3:
输入:"/home//foo/" 输出:"/home/foo" 解释:在规范路径中,多个连续斜杠需要用一个斜杠替换。
示例 4:
输入:"/a/./b/../../c/" 输出:"/c"
示例 5:
输入:"/a/../../b/../c//.//" 输出:"/c"
示例 6:
输入:"/a//b////c/d//././/.." 输出:"/a/b/c"
java的解决判法如下,我没有参考网上别人的答案,我的答案AC,并且时间复杂度超过79.09%,空间复杂度超过64.76%。
import java.util.Stack; class Solution { public String simplifyPath(String path) { Stack<Character> stack = new Stack<>(); int flag = 0; int flag2 = 0; for (int i = 0; i < path.length(); i++) { char c = path.charAt(i); //当路径中出现不是"."和"/"字符时,应该入栈 if (c != '.' && c != '/') { //当"."的个数为偶数,"/"大于0时,表示这个时候目录要cd到上一层 if (flag % 2 == 0 && flag2 >= 1) { //一共要向上的层数为flag/2 for (int j = 0; j < flag / 2; j++) { if (stack.size() > 0) { //出栈的第一个字符一定不会是/,这是由我们入栈的操作保证的 char d = stack.pop(); while (d != '/' && stack.size() > 0) d = stack.pop(); //直到我们出栈的字符为/时,暂停出栈 } } } else if (flag >= 1 && flag2 == 0) { //当"."的个数为基础,且"/"为0时,说明此时的几个"."字符是与字母连在一起的,需要入栈 stack.push('/'); for (int j = 0; j < flag; j++) { stack.push('.'); } } //上面解决了"."字符带来的出栈和入栈,现在要入栈我们此时取到的字符 if (flag2 >= 1) stack.push('/'); //如果"/"大于零,说明该生成下一级目录 stack.push(c); flag = 0; flag2 = 0; //"."个数增加,同时将之前可能取到的"/"个数清零,因为多余/是没用的 } else if (c == '.') { flag++; flag2 = 0; //"/"个数增加,同时判断此时"."个数,为1则表示在同一层,不起作用直接清0,为2表示需要向上一级 } else if (c == '/') { flag2++; if (flag == 2) { for (int j = 0; j < flag / 2; j++) { if (stack.size() > 0) { char d = stack.pop(); while (d != '/' && stack.size() > 0) d = stack.pop(); } } flag = 0; } else if (flag == 1) flag = 0; } } //for循环结束,可能最后取出了几个"."字符,这个时候需要判断是不是要向上一级目录 if (flag % 2 == 0) { for (int j = 0; j < flag / 2; j++) { if (stack.size() > 0) { char d = stack.pop(); while (d != '/' && stack.size() > 0) d = stack.pop(); } } } else if (flag > 1) { //如果"."字符个数大于1,且为奇数,则不是正确的指令,必须入栈该奇数个"." stack.push('/'); for (int j = 0; j < flag; j++) { stack.push('.'); } } //如果栈是空的 if (stack.size() == 0) return "/"; int f = 0; String[] arr = new String[stack.size()]; while (stack.size() != 0) { arr[f] = String.valueOf(stack.pop()); f++; } StringBuilder res = new StringBuilder(); for (int i = arr.length - 1; i >= 0; i--) { res.append(arr[i]); } return res.toString(); } public static void main(String[] args) { // String path = "/a//b////c/d//././/.."; String path = "/home/foo/.ssh/authorized_keys/"; Solution3 solution3 = new Solution3(); String s = solution3.simplifyPath(path); System.out.println(s); } }