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"
.
规律:
1、".."表示跳到上一层目录,删掉它上面挨着的一个路径。
2、"."表示当前目录,直接去掉。
3、如果有多个"/"只保留一个。
4、如果最后有一个"/",去掉不要。
Java:
public class Solution { public String simplifyPath(String path) { java.util.LinkedList<String> stack = new java.util.LinkedList<String>(); java.util.Set<String> set = new java.util.HashSet<String>(java.util.Arrays.asList("..", ".", "")); for (String str : path.split("/")){ if (str.equals("..") && !stack.isEmpty()) stack.pop(); if (!set.contains(str)) stack.push(str); } String result = ""; for (String str : stack) result = "/" + str + result; return result.isEmpty() ? "/" : result; } }
Python:
class Solution: # @param path, a string # @return a string def simplifyPath(self, path): stack, tokens = [], path.split("/") for token in tokens: if token == ".." and stack: stack.pop() elif token != ".." and token != "." and token: stack.append(token) return "/" + "/".join(stack)
C++:
class Solution { public: string simplifyPath(string path) { vector<string> v; int i = 0; while (i < path.size()) { while (path[i] == ‘/‘ && i < path.size()) ++i; if (i == path.size()) break; int start = i; while (path[i] != ‘/‘ && i < path.size()) ++i; int end = i - 1; string s = path.substr(start, end - start + 1); if (s == "..") { if (!v.empty()) v.pop_back(); } else if (s != ".") { v.push_back(s); } } if (v.empty()) return "/"; string res; for (int i = 0; i < v.size(); ++i) { res += ‘/‘ + v[i]; } return res; } };