19.9.26 简化路径 中等(需改进)


题目:

以 Unix 风格给出一个文件的绝对路径,你需要简化它。或者换句话说,将其转换为规范路径。

在 Unix 风格的文件系统中,一个点(.)表示当前目录本身;此外,两个点 (..) 表示将目录切换到上一级(指向父目录);两者都可以是复杂相对路径的组成部分。

请注意,返回的规范路径必须始终以斜杠 / 开头,并且两个目录名之间必须只有一个斜杠 /。最后一个目录名(如果存在)不能以 / 结尾。此外,规范路径必须是表示绝对路径的最短字符串。

示例 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"

代码:

 1 class Solution {
 2     private Stack<String> st;
 3     public String simplifyPath(String path) {
 4         char[] save = path.toCharArray();                        //将字符串拆分成数组
 5         char[] result = new char[save.length];            //存储排列好的字符数组
 6         
 7         if(save.length == 1)                       //当长度为1时,必为 / ,即可直接返回
 8             return path;          
 9         int j = 0;                             //结果数组的下标
10         for(int i = 0; i < save.length; i++){             //循环拆分数组
11             if(i != 0 && save[i - 1] == '/' && save[i] == '/'){  //除了第一位,其他位的多个斜杠不录入
12                 if(j != 1 && result[j - 1] == '/'){          //有时候删除点'.'后会遇到之前存起来的'/',但除去第一位的'/'
13                     if(i == save.length - 1){              //如果已经计算到最后一位,结果数组下标-1(因为每次添加完后都会让j+1指向下一个空)
14                         j--;    
15                     }
16                     continue;                        //多个斜杠,就继续循环不录入
17                 }
18             }
19             
20             if(j > 0 && result[j - 1] == '/' && save[i] == '/'){    //除去第一位,遇到上一个已经录入的斜杠,如果这一位也是斜杠,不录入斜杠
21                 if(i == save.length - 1){
22                     j--;    
23                 }
24                 continue;
25             }
26             
27             if(i == save.length - 1 && save[i] == '/'){              //最后一位是'/'就退出循环,不录入
28                 j--;                            
29                 break;
30             }
31             
32             if(i < save.length - 2 && save[i] == '.' && save[i + 1] == '.' && save[i + 2] == '.'){     //确定是两个点'.'以上,存起来
33                 int n = 0;
34                 int m = i;
35                 while(m < save.length && save[m] == '.'){
36                     n++;
37                     m++;
38                 }
39 
40                 for(int index = 1; index <= n; i++, index++){
41                     result[j++] = save[i]; 
42                 }
43                 i--;
44                 if(i == save.length - 1) --j;
45                 continue;
46             }
47             
48             if(i < save.length - 1 && save[i] == '.' && save[i + 1] == '/' && save[i - 1] != '.'){     //确定是一个点'.'后,删除前一位已存储的'/',不录入
49                 continue;
50             }
51             
52             if(save[i] == '.' && save[i - 1] == '.' && save[i - 2] != '.'){   //确定是两个点'.'后,删除前两位已存储的'/'和目录,不录入
53                 if(i < save.length- 1 && save[i + 1] == '/' || i == save.length - 1){
54             
55                     if(j > 1){
56                         --j;
57                         while(result[j - 1] != '/' && j > 1){
58                             --j;
59                         }
60                     }
61                 }
62                 else result[j++] = save[i];
63                 if(i == save.length - 1) --j;
64                 
65                 continue;
66             }
67           
68             if(i < save.length - 1 && save[i] == '.' && save[i + 1] == '.'){   //确定是两个'.'后,对第一个'.'不录入
69                 if(i < save.length - 2 && save[i + 2] != '/'){
70                     result[j++] = save[i];
71                     continue;
72                 }
73                 continue;
74             }
75             
76             if(i == save.length - 1 && save[i] =='.'){
77                 
78                 --j;
79                 
80                 break;
81             }
82                
83             result[j++] = save[i];
84             
85            
86             if(i == save.length - 1) --j;
87             
88         }
89         
90         if(j > 1 && result[j] == '/') --j;
91         
92         char[] result1 = new char[j + 1];
93         for(int i = 0; i <= j; i++){
94             result1[i] = result[i];
95         }
96         String resultCurr = new String(result1);
97         return resultCurr;
98     }
99 }    

心得:

1、一开始想的时候,是想着这样暴力解法的,想了大概的几种情况,就开始调试,然后边调试边改,完全忘了这是一个关于栈的题目,所以代码也特别混乱;

2、本来觉得这道题怎么这样子,就一直在找漏洞,都没有知识点,最后做完看题解才明白有很简单的做法;

3、就是把字符串用正则或者split的方法拆分成字符串数组,然后压入栈中,可以说 '/' 是完全没用的,重要的是 '.' 和字母字符串,最后拆分好再添加 '/'就好了。

4、以后思考题目不要再太容易陷入暴力解法了,学会一下转弯。

猜你喜欢

转载自www.cnblogs.com/wasi-991017/p/11593826.html