小小程序媛  
得之坦然,失之淡然,顺其自然,争其必然

题目

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

分析

这道题的要求是简化一个Unix风格下的文件的绝对路径。

字符串处理,由于”..”是返回上级目录(如果是根目录则不处理),因此可以考虑用栈记录路径名,以便于处理。需要注意几个细节:

  1. 重复连续出现的’/’,只按1个处理,即跳过重复连续出现的’/’;

  2. 如果路径名是”.”,则不处理;

  3. 如果路径名是”..”,则需要弹栈,如果栈为空,则不做处理;

  4. 如果路径名为其他字符串,入栈。

最后,再逐个取出栈中元素(即已保存的路径名),用’/’分隔并连接起来,不过要注意顺序呦。

时间复杂度:O(n)

空间复杂度:O(n)

AC代码

class Solution {
public:
    string simplifyPath(string path) {
        if (path.empty())
            return string();

        stack<string> st;
        int len = path.length();

        for (int i = 0; i < len;)
        {
            //跳过/
            while (i < len && path[i] == '/')
                i++;
            //找到以/分隔的目录名
            string s = "";
            while ( i < len && path[i] != '/')
            {
                s += path[i];
                i++;
            }

            //如果为..则需要弹栈
            if (s == ".." && !st.empty())
                st.pop();
            //如果既不是. 也不是.. 则需要入栈
            else if (s != "" && s != "." && s != "..")
                st.push(s);

        }
        //如果栈空,则为根目录
        if (st.empty())
        {
            return "/";
        }

        //否则链接各级目录并返回
        string ret;
        while (!st.empty())
        {
            ret = '/' + st.top() + ret;
            st.pop();
        }

        return ret;
    }

};

GitHub测试程序源码

posted on 2015-10-03 14:20  Coding菌  阅读(168)  评论(0编辑  收藏  举报