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

题意分析: 

给定文件的Unix型绝对路径,请简化它。 或者说,将其转换为规范路径。在UNIX型的文件系统中,一个点(.)指的是当前目录,两个点(..)指返回上级目录。 

注:返回的规范路径必须始终以斜杠(/)开头,并且两个目录名之间必须只有一个斜杠(/),最后一个目录名称(如果存在)不得后接斜杠(/)来结尾。另外,规范路径必须是表示绝对路径的最短字符串。

解答如下:

方法一(堆栈法)

由题目中的6个例子可以总结到:目录如果后接"."则直接去掉".",如果后接".."则删掉它的上级目录。如果被给绝对路径为空则返回"/",如果被给绝对路径中有多个连续"/"只保留一个。正因为如此,可以把被给绝对路径看做是由一个或多个"/"分割开的多个子字符串,利用两个while循环可以把这些子字符串分别提取出来并一一处理,而这些被提取出来的子字符串只有三种情况:①路径名称;②两个点"..";③一个点".",所以用if条件语句进行判断很容易求解。

class Solution{
public:
    string simplifyPath(string path){
        vector<string> tmp;
        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( !tmp.empty() )   tmp.pop_back();}            //返回上一级目录
            else if( s != "." )
                tmp.push_back(s);                             //tmp用于存放规范路径每一级的目录名称                       
        }
        if (tmp.empty())  return "/";
        string res;                                            
        for (int i = 0; i < tmp.size(); ++i) {
            res += '/' + tmp[i];
        }
    return res;
    }
};

提交后的结果如下:  

 

方法二(使用函数分隔字符串):

用stringstream函数替代两个while循环来分隔字符串,然后对每一个子字符串进行处理,大体的思路与方法一是一致的。

class Solution {
public:
    string simplifyPath(string path) {
        string res, t;
        stringstream subs (path);
        vector<string> tmp;
        while (getline(subs, t, '/')) {                       //按斜杠'/'来分隔字符串,其中连续多个斜杠也会被分隔
            if( t == ".." )
            {if( !tmp.empty() )   tmp.pop_back();}            //返回上一级目录
            else if( t != "." && t != "" )                    //这里多了一种为空的情况
                tmp.push_back(t);
        }
        for (string s : tmp) res += "/" + s;
        return res.empty() ? "/" : res;
    }
};

提交后的结果如下:  

 

日积月累,与君共进,增增小结,未完待续。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值