Given an absolute path for a file (Unix-style), simplify it.
For example,
path = "/home/", => "/home"
path = "/a/./b/../../c/", => "/c"
Corner Cases:
- 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".
一刷
题解:
先Split整个path by "/", 然后建立一个stack / deque或者doubly linked list。 遍历split好的数组, 当数组当前元素p不为 "", "."和".."的时候,我们push p 入栈, 否则当p为".."并且栈非空的情况下,我们pop上一个元素出栈。11ms
public class Solution {
public String simplifyPath(String path) {
if (path == null || path.length() < 2) return path;
Stack<String> stack = new Stack<>();
for (String p : path.split("/")) {
if (!p.equals(".") && !p.equals("..") && !p.equals("")) stack.push(p);
else if (p.equals("..") && !stack.isEmpty()) stack.pop();
}
StringBuilder res = new StringBuilder();
while (!stack.isEmpty()) res.insert(0, stack.pop()).insert(0, "/");
return res.length() == 0 ? "/" : res.toString();
}
}
问题在于,对于StringBuilder,每次在开头insert时间复杂度很高。想办法从头部开始,可以考虑双向链表。10ms。感觉并没有很大提升。
public class Solution {
public String simplifyPath(String path) {
if (path == null || path.length() < 2) return path;
LinkedList<String> list = new LinkedList<String>();
for (String p : path.split("/")) {
if (!p.equals(".") && !p.equals("..") && !p.equals("")) list.add(p);
else if (p.equals("..") && !list.isEmpty()) list.remove(list.size()-1);
}
StringBuilder res = new StringBuilder();
res.append("/");
while (!list.isEmpty()) res.append(list.poll()).append("/");
if(res.length()!=1) res.deleteCharAt(res.length()-1);
return res.toString();
}
}