leetcode【71】Simplify Path

问题描述:

Given an absolute path for a file (Unix-style), simplify it. Or in other words, convert it to the canonical path.

In a UNIX-style file system, a period . refers to the current directory. Furthermore, a double period .. moves the directory up a level. For more information, see: Absolute path vs relative path in Linux/Unix

Note that the returned canonical path must always begin with a slash /, and there must be only a single slash / between two directory names. The last directory name (if it exists) must not end with a trailing /. Also, the canonical path must be the shortest string representing the absolute path.

 

Example 1:

Input: "/home/"
Output: "/home"
Explanation: Note that there is no trailing slash after the last directory name.

Example 2:

Input: "/../"
Output: "/"
Explanation: Going one level up from the root directory is a no-op, as the root level is the highest level you can go.

Example 3:

Input: "/home//foo/"
Output: "/home/foo"
Explanation: In the canonical path, multiple consecutive slashes are replaced by a single one.

Example 4:

Input: "/a/./b/../../c/"
Output: "/c"

Example 5:

Input: "/a/../../b/../c//.//"
Output: "/c"

Example 6:

Input: "/a//bc/d//././/.."
Output: "/a/b/c"

源码:

一点点的遍历就行了,注意“...”或者更多'.'的情况,这个时候他们和abcd这些字母一样。最近leetcode可能有点问题,我在评论里面那些自称是超越100%的c++程序都试了一下,最高就是73.43%。

class Solution {
public:
    string simplifyPath(string path) {
        string result;
        int index = 0;
        while(index<path.size()){
            if(path[index] == '/'){
                if(index==0 || path[index-1]!='/'){
                    result.append("/");
                }
                index++;
                continue;
            }
            else if(path[index] == '.'){
                int tmp_long = index;
                while(tmp_long<path.size() && path[tmp_long] != '/')    tmp_long++;
                string tmp_str = path.substr(index, tmp_long-index);
                if(tmp_str == "."){
                    index+=2;   continue;
                }
                else if(tmp_str == ".."){
                    if(result != "/"){
                        result.pop_back();
                        int n = result.size(), i=n-1;
                        while(result[i--]!='/'){
                            result.pop_back();
                        }
                    }
                    index += 3;
                    continue;
                }
            }
            int tmp = index;
            while(path[index] != '/' && index<path.size()){
                index++;
            }
            string tmp_str1 = path.substr(tmp, index-tmp);
            result.append(tmp_str1);
        }
        if(result[result.size()-1] == '/' && result != "/")   result.pop_back();
        return result;
    }
};
 

后来看到网上一个同学的做法,用一个vector存下所有文件夹名字,然后在加/,逻辑上简单很多。性能并没有提升,甚至因为是vector,空间复杂度还高了点。

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;
    }
};

竟然有大神有自动机写的,我们来瞅瞅

class Solution {
public:
    string simplifyPath(string path) {
        string res;
        
        // some flag to kepp state.
        int state = 0;  // 0: last char is [char]
                        // 1: last char is '/'
                        // 2: last char is '.'
                        // 3: last char is ".."
        
        if (path.size() != 0 && path[path.size()-1]!='/') path.push_back('/');
        
        int len = path.size();
        for(int i = 0; i < len; i++) {
            char c = path[i];
            
            if (state == 0) {
                if (c == '/') { res.push_back('/'); state = 1; }
                else if (c == '.') state = 2;
                else res.push_back(c);
            } else if (state == 1) {
                if (c == '/') {}
                else if (c == '.') { state = 2; }
                else {
                    res.push_back(c); state = 0;
                }
            } else if (state == 2) {
                if (c == '/') state = 1;
                else if (c == '.') {
                    // '..'
                    state = 3;
                } else {
                    res.push_back('.'); res.push_back(c); state = 0;
                }
            } else if (state == 3) {
                if (c == '/') {
                    // go back
                    res.pop_back(); // pop '/'
                    while(res.size() != 0 && *res.rbegin() != '/') {
                        res.pop_back(); // pop anthing until '/'
                    }
                    if (res.size() == 0) res.push_back('/');
                    state = 1;
                } else {
                    res.push_back('.'); 
                    res.push_back('.');
                    res.push_back(c);
                    state = 0;
                }
            }
            //cout << state << " " << c << " " << res <<  endl;
        }
        
        if ((state == 1 && res.size() != 1)) res.pop_back();
        return res;
    }
};

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值