文章目录
71. 简化路径:
给你一个字符串 path
,表示指向某一文件或目录的 Unix 风格 绝对路径 (以 '/'
开头),请你将其转化为更加简洁的规范路径。
在 Unix 风格的文件系统中,一个点(.
)表示当前目录本身;此外,两个点 (..
) 表示将目录切换到上一级(指向父目录);两者都可以是复杂相对路径的组成部分。任意多个连续的斜杠(即,'//'
)都被视为单个斜杠 '/'
。 对于此问题,任何其他格式的点(例如,'...'
)均被视为文件/目录名称。
请注意,返回的 规范路径 必须遵循下述格式:
- 始终以斜杠
'/'
开头。 - 两个目录名之间必须只有一个斜杠
'/'
。 - 最后一个目录名(如果存在)不能 以
'/'
结尾。 - 此外,路径仅包含从根目录到目标文件或目录的路径上的目录(即,不含
'.'
或'..'
)。
返回简化后得到的 规范路径 。
样例 1:
输入:
path = "/home/"
输出:
"/home"
解释:
注意,最后一个目录名后面没有斜杠。
样例 2:
输入:
path = "/../"
输出:
"/"
解释:
从根目录向上一级是不可行的,因为根目录是你可以到达的最高级。
样例 3:
输入:
path = "/home//foo/"
输出:
"/home/foo"
解释:
在规范路径中,多个连续斜杠需要用一个斜杠替换。
样例 4:
输入:
path = "/a/./b/../../c/"
输出:
"/c"
提示:
1 <= path.length <= 3000
path
由英文字母,数字,'.'
,'/'
或'_'
组成。path
是一个有效的 Unix 风格绝对路径。
分析:
- 面对这道算法题目,二当家的再次陷入了沉思。
- 直接模拟即可,关键是选对数据结构,就会很容易解决。
- 按照
'/'
将完整路径拆分成组,用栈存储简化后的路径结构,根据情况走分支逻辑:- 如果是
'.'
或者空格
:'空格'
没有意义,'.'
表示当前目录,都直接跳过,不做处理。 - 如果是
'..'
:表示要向上层目录跳转,此时只要没有到根目录,就要向上跳,所以只要栈不为空,就做出栈操作。 - 其他的字符串:都当作是有效的目录名,做入栈操作。
- 如果是
- 遍历处理完之后,再按照队列的方式,将简化后的路径拼接。
题解:
rust:
rust
impl Solution {
pub fn simplify_path(path: String) -> String {
let mut stack = Vec::new();
path.split('/').for_each(|name| match name {
"." | "" => (),
".." => {
stack.pop();
}
_ => stack.push(name),
});
"/".to_string() + &stack.join("/")
}
}
go:
go
func simplifyPath(path string) string {
var stack []string
for _, name := range strings.Split(path, "/") {
if name == ".." {
if len(stack) > 0 {
stack = stack[:len(stack)-1]
}
} else if name != "" && name != "." {
stack = append(stack, name)
}
}
return "/" + strings.Join(stack, "/")
}
c++:
cpp
class Solution {
public:
string simplifyPath(string path) {
stringstream ss(path);
vector<string> stack;
string name = "";
while (getline(ss, name, '/')) {
if (name == "..") {
if (!stack.empty()) {
stack.pop_back();
}
} else if (!name.empty() && name != ".") {
stack.push_back(move(name));
}
}
string ans;
if (stack.empty()) {
ans = "/";
} else {
for (string &name: stack) {
ans += "/" + move(name);
}
}
return ans;
}
};
python:
python
class Solution:
def simplifyPath(self, path: str) -> str:
names = path.split("/")
stack = list()
for name in names:
if name == "..":
if stack:
stack.pop()
elif name and name != ".":
stack.append(name)
return "/" + "/".join(stack)
java:
java
class Solution {
public String simplifyPath(String path) {
String[] names = path.split("/");
Deque<String> stack = new ArrayDeque<String>();
for (String name : names) {
if ("..".equals(name)) {
if (!stack.isEmpty()) {
stack.pollLast();
}
} else if (name.length() > 0 && !".".equals(name)) {
stack.offerLast(name);
}
}
StringBuilder ans = new StringBuilder();
if (stack.isEmpty()) {
ans.append('/');
} else {
while (!stack.isEmpty()) {
ans.append('/');
ans.append(stack.pollFirst());
}
}
return ans.toString();
}
}
非常感谢你阅读本文~
欢迎【点赞】【收藏】【评论】三连走一波~
放弃不难,但坚持一定很酷~
希望我们大家都能每天进步一点点~
本文由 二当家的白帽子:https://le-yi.blog.csdn.net/ 博客原创~