【leetcode】71. Simplify Path
题目说明
https://leetcode-cn.com/problems/simplify-path/description/
给定一个文档 (Unix-style) 的完全路径,请进行路径简化。
例如,
path = "/home/", => "/home"
path = "/a/./b/../../c/", => "/c"
解法1
本题的关键在于,需要对字符串按'/'进行分隔,分隔后得到容器,遍历分隔该容器,用栈来存储元素,来对于'.'需要跳过,对于'..'则需要删除栈顶元素(即前一个保存的元素)。
这里用find实现了一个分隔函数。
/*
* 时间复杂度:O(n)
* 先将字符串按/进行分隔
* 然后对所分隔子串进行遍历,用栈来存储子串
* 若为.,则不入栈
* 若为..,则本身不入栈,且顶栈元素需要弹出
* 若为空,则不入栈
* 最终,再将栈元素转换到string类型中。
*/
string simplifyPath(string path) {
stack<string> stack1;
vector<string> vec;
string res;
split(path, vec, "/");
for (int i = 0; i < vec.size(); i ++){
if (vec[i] == "."){
continue;
}else if (vec[i] == ".."){
if (stack1.size())
stack1.pop();
continue;
}
if (vec[i].size()){
stack1.push(vec[i]);
}
}
while (stack1.size()){
res = '/' + stack1.top() + res;
stack1.pop();
}
if (res.empty())
res = '/';
return res;
}
int split(string s,vector<string> &v, string c){
std::string::size_type pos1 = 0, pos2 = 0;
pos2 = s.find(c);
while(pos2 != string::npos){
v.push_back(s.substr(pos1, pos2 - pos1));
pos1 = pos2 + c.size();
pos2 = s.find(c, pos1);
}
if (pos1 != s.size()){
v.push_back(s.substr(pos1));
}
return 0;
}
解法2
基本思路与上述解法一致,这里用stringstream的getline函数实现分隔,用vector容器来存储元素,pop_back方法可以删除尾部元素。
/*
* 时间复杂度:O(n)
* 使用输入输出流stringstream的getline来分隔字符串
*/
string simplifyPath2(string path) {
vector<string> vec;
string res;
string tmp;
stringstream ss(path);
while (getline(ss, tmp, '/')){
if (tmp == "."){
continue;
}else if (tmp == ".."){
if (vec.size())
vec.pop_back();
continue;
}
if (tmp.size()){
vec.push_back(tmp);
}
}
for (auto e:vec){
res = res + "/" + e;
}
if (res.empty())
res = '/';
return res;
}