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"
.
Java doc:
Suppose x is a list known to contain only strings. The following code can be used to dump the list into a newly allocated array of String:
String[] y = x.toArray(new String[0]);
Note that toArray(new Object[0]) is identical in function to toArray().
public static void main(String[] args){
LinkedList<Integer> stack = new LinkedList<>();
stack.push(1);
stack.push(2);
stack.push(3);
stack.push(4);
Integer[] arr = stack.toArray(new Integer[0]);
for(int i = 0; i < arr.length; i++){
System.out.println(arr[i]);
}
}
至于返回的顺序: 上面代码中的 arr 为 {4, 3, 2, 1},也就是按照 stack 依次 pop()得到的顺序。
回到Simplify Path这个题, 有一个小技巧,自己写的时候没有引入index这个变量,而是判断了一下 当前 StringBuilder 长度是否为0, 觉得有点不妥但是没有想到好的办法。 学习了Code Ganker大神的写法,每次循环开始的时候把 i 的值赋给 index,如果 当前元素是 ‘/’, 则 i 的值没变, 就跳过了下面的判断。
public class Solution {
public String simplifyPath(String path) {
if(path == null || path.length() == 0){
return "";
}
StringBuilder res = new StringBuilder();
LinkedList<String> stack = new LinkedList<>();
int i = 0;
while(i < path.length()){
StringBuilder item = new StringBuilder();
int index = i;
while(i < path.length() && path.charAt(i) != '/'){
item.append(path.charAt(i));
i++;
}
if(index != i){ // 这里避免了在stringbuilder为空的情况下的多余判断
if(item.toString().equals("..")){
if(!stack.isEmpty()){
stack.pop();
}
}else if(item.toString().equals(".") /*|| item.length() == 0*/){
// do nothing
}else{
stack.push(item.toString());
}
}
i++;
}
if(stack.isEmpty()){
return "/";
}
String[] arr = stack.toArray(new String[0]);
for(int ii = arr.length - 1; ii >= 0; ii--){
res.append('/');
res.append(arr[ii]);
}
return res.toString();
}
}