[C++]LeetCode: 117 Simplify Path (简化Unix路径 list双向链表)

题目:

Given an absolute path for a file (Unix-style), simplify it.

For example,

path = "/home/", => "/home"

path = "/a/./b/../../c/", => "/c"

click to show corner cases.

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".

思路:这是Linux内核中较常见的一个操作,就是对一个输入的文件路径进行简化。我们先来了解一下这些符号在Unix路径中代表的意义:

  • “/.” 表示本级目录,可以忽略
  • “/..” 表示返回上一级目录,即若上一级目录存在,连同“/..”一并删除,否则只删除“/..”
  • 若去除冗余后路径为空,返回“/”
  • 若包含多个连续“/”, 删除多余的“/”

在了解了我们要做的操作后,我们想到要维护一个栈,对于每一个块(用“/”作为分隔符)进行分析,如果遇到“../”表示要回到上一层,那么就进行出栈操作(如果栈不为空),如果遇到“./”表示在当前层,则直接跳过,不作操作,其他文件的路径则直接进栈,放在栈尾部。最后根据栈中的内容转换成路径即可,注意我们这里使用list双向链表的特性,和java LinkedList类似,list也包含了栈和队列的实现。这样在还原路径时,我们就不需要再维护一个栈来解决路径的顺序问题了,直接从栈头出栈就可以了。

Attention:

1. C++ list双向链表。

获得元素函数:front(); back();

进出栈/队列函数:push_back(); pop_back(); push_front(); pop_front();

我们可以根据自己的需求,来选择合适的函数进行操作。

2. Stringcompare函数

int compare (const string& str) const;

如果相等,返回0;

if(tmp.compare(".") == 0)

3. 如果去除冗余后路径为空,返回“/”

if(ret.size() == 0)
            return "/";

4. 注意如何获取分隔符“/”之间的元素,并进行操作,我们遍历一遍path.

 while(i < path.size())
        {
            int index = i;
            //截取‘/’之间的字符串
            string tmp;
            while(i < path.size() && path[i] != '/')
            {
                tmp += path[i];
                i++;
            }

5. 先获取队列头的元素,再pop_front(), 转换成正常路径。

while(!stk.empty())
        {
            ret += "/" + stk.front();
            stk.pop_front();
        }

复杂度:O(N) 空间也是O(N),栈的大小

AC Code:

class Solution {
public:
    string simplifyPath(string path) {
        if(path.size() == 0) return "";
        list<string> stk;
        string ret;

        int i = 0;
        while(i < path.size())
        {
            int index = i;
            //截取‘/’之间的字符串
            string tmp;
            while(i < path.size() && path[i] != '/')
            {
                tmp += path[i];
                i++;
            }

            if(index != i)
            {
                if(tmp.compare(".") == 0)
                {
                   continue;
                }
                else if(tmp.compare("..") == 0)
                {
                    if(!stk.empty())
                    {
                        stk.pop_back();
                    }
                }
                else
                {
                    stk.push_back(tmp);
                }
            }

            i++;
        }

        while(!stk.empty())
        {
            ret += "/" + stk.front();
            stk.pop_front();
        }

        if(ret.size() == 0)
            return "/";

        return ret;
    }
};

这道题,我们也可以用数组来存储分隔符之间的元素,这样就可以直接通过下标来操作元素。数组也有push_back和pop_back函数。可以看下这篇博文:Simplify Path

不过通过这道题,了解到C++ list数据结构的强大和使用方便。以后要好好利用。

时间: 2024-12-18 05:17:54

[C++]LeetCode: 117 Simplify Path (简化Unix路径 list双向链表)的相关文章

[LeetCode] 71. Simplify Path 简化路径

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 th

【LeetCode】Simplify Path

Simplify Path Given an absolute path for a file (Unix-style), simplify it. Given an absolute path for a file (Unix-style), simplify it. For example,path = "/home/", => "/home"path = "/a/./b/../../c/", => "/c"

leetCode 71.Simplify Path(化简路径) 解题思路和方法

Simplify Path Given an absolute path for a file (Unix-style), simplify it. For example, path = "/home/", => "/home" path = "/a/./b/../../c/", => "/c" click to show corner cases. Corner Cases: Did you consider

leetcode 71 Simplify Path

题目连接 https://leetcode.com/problems/simplify-path/ Simplify Path Description Given an absolute path for a file (Unix-style), simplify it. For example,path = "/home/", => "/home"path = "/a/./b/../../c/", => "/c"

【LeetCode】Simplify Path 解题报告

[题目] Given an absolute path for a file (Unix-style), simplify it. For example, path = "/home/", => "/home" path = "/a/./b/../../c/", => "/c" click to show corner cases. Corner Cases: Did you consider the case

[Leetcode] Simplify path 简化路径

Given an absolute path for a file (Unix-style), simplify it. For example,path ="/home/", =>"/home"path ="/a/./b/../../c/", =>"/c" click to show corner cases. Corner Cases: Did you consider the case where path 

【LeetCode每天一题】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.

[LeetCode][Java] Simplify Path

题目: Given an absolute path for a file (Unix-style), simplify it. For example, path = "/home/", => "/home" path = "/a/./b/../../c/", => "/c" click to show corner cases. Corner Cases: Did you consider the case w

leetcode No71. Simplify Path

Question: 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 = "/../