欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

leetcode【71】Simplify Path

程序员文章站 2022-03-04 18:22:46
...

问题描述:

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//b////c/d//././/.."
Output: "/a/b/c"

源码:

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

leetcode【71】Simplify Path

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

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

leetcode【71】Simplify Path

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