Given an absolute path for a file (Unix-style), simplify it.
For example,
path = "/home/"
, => "/home"
path = "/a/./b/../../c/"
, => "/c"
- Did you consider the case where path =
"/../"
?
In this case, you should return"/"
. - Another corner case is the path might contain multiple slashes
'/'
together, such as"/home//foo/"
.
In this case, you should ignore redundant slashes and return"/home/foo"
.
本来觉得这种题不是很重要,刚才跑步的时候看到LY,说他去Google on site的时候考了这道题,于是赶紧回来复习一下。
基本思路是这样的,用一个stack来记录有效的路径。注意,压入stack的有效路径无需加上"/",在最后出栈的时候补上就行了。这样做可以将问题简化不少。
首先,把原字符串对于"/"进行split,得到一个字符串数组。然后依次遍历这个数组中的每个元素,会有如下几种情况出现:
1. 当前字符串是"."或者为空。在Linux中,一个点代表当前目录,而空字符串则意味着两个斜杠相邻。遇到这两种情况,直接continue,因为他们不会对有效路径造成任何影响。
2. 当前字符串是".."。同样,Linux的路径中两个连续的点意味着返回上级目录。所以此时,如果栈不为空,则pop出栈顶元素。若栈为空,则continue。
3. 当前字符串是其它。这意味着该字符串为一个目录或文件名,所以我们应该将其push到stack中,作为有效路径的一部分。
在遍历字符串数组的所有元素之后,我们可以用一个StringBuilder来建立有效路径。具体的方法是这样的,依次将栈的每个元素pop出来,插入StringBuilder的第一个位置,然后在每两个栈内元素之间,加入一个斜杠,直到栈为空。值得注意的是,如果一开始栈就为空,那么直接返回一个斜杠,这种情况相当于Corner Case中的第一种情况。
代码如下:
public class Solution {
public String simplifyPath(String path) {
if(path==null) return null;
String[] files = path.split("/");
Stack<String> stack = new Stack<String>();
for(int i=0; i<files.length; i++) {
if(files[i].equals(".") || files[i].equals("")) {
continue;
}
else if(files[i].equals("..")) {
if(!stack.isEmpty()) stack.pop();
}
else {
stack.push(files[i]);
}
}
StringBuilder res = new StringBuilder();
if(stack.isEmpty()) return "/";
else {
while(!stack.isEmpty()) {
res.insert(0, stack.pop());
res.insert(0, "/");
}
}
return res.toString();
}
}