LeetCode #71 Simplify Path

本文介绍了一种用于简化Unix风格文件路径的算法,并提供了详细的解题思路。通过使用栈结构存储路径段,结合对特殊符号(如.和..)的处理,最终实现了路径的有效简化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目

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

For example,
path = “/home/”, => “/home”
path = “/a/./b/../../c/”, => “/c”

解题思路

这道题直接想到的就是利用一个栈,每次把一个字符 push 进去,遇到 ... 时再进行 pop 操作,但是必须要留意文件名也可以是 ., .. 或者 ... 开头!如果没有好的方法的话就需要非常复杂的判断才能完成简化。我自己在做题的时候,由于判断条件不够完善,踩了以下字符串的坑:

"/abc//flo/" 双斜杠
"/..."
"/."
"/../"
"/..*",其中 "*" != "/"
"/.*",其中 "*" != "/"

后来觉得实在太复杂了没有办法,就去看了 LeetCode 上面一些大神写的代码,才发现解题的思路原来可以如此简单:

  • 先把整个路径字符串以字符 '/' 进行分割,得到路径中所有文件名的字符串数组;
  • 遍历该数组中的每个字符串,如果遇到空字符串或表示当前目录的字符串 ".",则不进行任何操作;
  • 如果遇到表示上一级目录的字符串 ".." 且当前的栈不是空的,则需要进行一次 pop 操作,把上一级目录的文件名去掉,而如果当前的栈是空的,则不进行任何操作;
  • 不是上述两种情况的,说明是一个普通的文件名字符串,则调用 push 压进栈中;
  • 最后,把栈中的字符串通过字符 "/" 连接起来就可以得到最后的结果。

Java代码实现

class Solution {
    public String simplifyPath(String path) {
        String[] files = path.split("/");
        LinkedList<String> simplifyFiles = new LinkedList<>();

        for (String str : files) {
            if (str.equals(".") || str.equals("")) { continue; }
            if (str.equals("..") && !simplifyFiles.isEmpty()) { simplifyFiles.removeLast(); }
            else if (!str.equals("..")) { simplifyFiles.addLast(str); }
        }

        StringBuffer simplifiedPath = new StringBuffer();
        for (String str : simplifyFiles) {
            simplifiedPath.append("/" + str);
        }

        // 当最后得到的简化路径没有文件名时,需要返回 "/"
        return simplifiedPath.length() == 0 ? "/" : simplifiedPath.toString();
    }
}

C++代码实现

如果使用C++实现算法功能的话,可以利用 stringstream 这个类把输入的路径字符串转化为字符流,然后利用 getline 函数来实现字符串的分割:

class Solution {
public:
    string simplifyPath(string path) {
        stringstream ss(path);
        string tmp;
        vector<string> files;

        // getline函数的第三个参数表示读取到'/'字符时停止
        while (getline(ss, tmp, '/')) {
            if (tmp == "." || tmp == "") { continue; }
            if (tmp == ".." && !files.empty()) { files.pop_back(); }
            else if (tmp != "..") { files.push_back(tmp); }
        }

        string rst;
        for (auto str : files) { rst += "/" + str; }

        // 当最后得到的简化路径没有文件名时,需要返回 "/"
        return rst.length() == 0 ? "/" : rst;
    }
};
### LeetCode Problem 71 Simplify Path Problem 71 on LeetCode is titled "Simplify Path," which involves simplifying a given Unix-style path to its canonical form. The task does not directly involve stacks as the primary data structure, but one can implement solutions that utilize stack-like behavior or other methods. The goal of this problem is to convert an absolute path into its simplest and most normalized form by resolving `..` (parent directory), `.` (current directory), and multiple slashes (`//`). For instance: - Input: `/home/` - Output: `/home` A common approach uses string manipulation techniques rather than explicitly implementing a stack from scratch like in some problems such as those mentioned in another context[^2]. However, understanding how paths are processed could be analogous to operations performed when managing elements within a stack where directories might be pushed onto or popped off depending on whether they represent moving up or down through filesystem levels. For solving this particular challenge without focusing specifically on traditional stack implementation details found elsewhere [^3]: ```cpp #include <iostream> #include <sstream> #include <vector> using namespace std; string simplifyPath(string path) { stringstream ss(path); vector<string> tokens; string token, res = "", prev; while(getline(ss,token,&#39;/&#39;)){ if(token==".." && !tokens.empty()) tokens.pop_back(); else if((!token.empty())&&(token!=".")&&(token!="..")) tokens.push_back("/"+token); } for(auto& s : tokens){ res += s; } return res.empty()? "/":res; } ``` This code snippet demonstrates handling various cases including consecutive slashes, current-directory symbols `.`, parent-directory symbols `..`. It iterates over parts split by slash characters, applying rules similar to pushing valid segments onto a list (acting similarly to a stack&#39;s functionality) and popping them upon encountering double dots indicating upward traversal beyond root level isn&#39;t possible thus ignored implicitly during construction phase only adding non-empty strings representing actual traversals back together forming final simplified result.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值