leetcode 面试经典 150 题:简化路径

devtools/2025/1/24 5:13:54/
链接简化路径
题序号71
题型字符串
解法
难度中等
熟练度✅✅✅

题目

  • 给你一个字符串 path ,表示指向某一文件或目录的 Unix 风格 绝对路径 (以 ‘/’ 开头),请你将其转化为 更加简洁的规范路径。

  • 在 Unix 风格的文件系统中规则如下:
    一个点 ‘.’ 表示当前目录本身。
    此外,两个点 ‘…’ 表示将目录切换到上一级(指向父目录)。
    任意多个连续的斜杠(即,‘//’ 或 ‘///’)都被视为单个斜杠 ‘/’。
    任何其他格式的点(例如,‘…’ 或 ‘…’)均被视为有效的文件/目录名称。

  • 返回的 简化路径 必须遵循下述格式:
    始终以斜杠 ‘/’ 开头。
    两个目录名之间必须只有一个斜杠 ‘/’ 。
    最后一个目录名(如果存在)不能 以 ‘/’ 结尾。
    此外,路径仅包含从根目录到目标文件或目录的路径上的目录(即,不含 ‘.’ 或 ‘…’)。
    返回简化后得到的 规范路径 。

  • 示例 1
    输入:path = “/home/”
    输出:“/home”
    解释:
    应删除尾随斜杠。

  • 示例 2
    输入:path = “/home//foo/”
    输出:“/home/foo”
    解释:
    多个连续的斜杠被单个斜杠替换。

  • 示例 3
    输入:path = “/home/user/Documents/…/Pictures”
    输出:“/home/user/Pictures”
    解释:
    两个点 “…” 表示上一级目录(父目录)。

  • 示例 4
    输入:path = “/…/”
    输出:“/”
    解释:
    不可能从根目录上升一级目录。

  • 示例 5
    输入:path = “/…/a/…/b/c/…/d/./”
    输出:“/…/b/d”
    解释:
    “…” 在这个问题中是一个合法的目录名。

  • 提示
    1 <= path.length <= 3000
    path 由英文字母,数字,‘.’,‘/’ 或 ‘_’ 组成。
    path 是一个有效的 Unix 风格绝对路径。

题型

  1. 核心思想:该题使用(Stack)这种数据结构来模拟路径的遍历和回退过程。
  2. 复杂度:时间复杂度是 O(n),其中 n 是路径字符串的长度,因为我们需要遍历整个字符串。空间复杂度也是 O(n),因为我们需要存储路径的有效部分。
  3. c++ 实现算法
class Solution {
public:std::string simplifyPath(std::string path) {std::vector<std::string> stack;//定义一个//创建了一个 std::stringstream 对象 ss,并将字符串 path 作为其初始内容。//这样做的目的是为了方便地对路径字符串进行分割和读取操作。std::stringstream ss(path);//dir 用于存储从 stringstream 中读取的每个目录std::string dir;//使用 getline 函数从 stringstream 中按 / 分割读取路径的每个部分,直到没有更多内容可读。while (getline(ss, dir, '/')) {//如果目录为空字符串或为 ".",表示当前目录,不做任何操作,继续下一次循环。if (dir.empty() || dir == string">".") {continue;}//如果目录为 "..",表示返回上一级目录。如果不为空,则弹出顶元素(即移除上一级目录)。else if (dir == string">"..") {if (!stack.empty()) {stack.pop_back();}}//否则,将该目录压入中。 else {stack.push_back(dir);}}//初始化一个空字符串 simplified,用于存储简化后的路径。然后遍历中的每个目录,//将其添加到 simplified 字符串中,并在每个目录前加上 /。std::string simplified;for (const std::string& d : stack) {simplified += string">"/" + d;}//simplified 为空字符串,说明路径简化后是一个根目录,返回 /。否则,返回 simplified。return simplified.empty() ? string">"/" : simplified;}
};
  1. 算法推演
  • 初始化
    stack:[]
    ss:/a/./b/…/…/c/

  • 遍历路径

    • 读取第一个部分:“”
      字符串,忽略。
      stack:[]

    • 读取第二个部分:“a”
      将 “a” 压入
      stack:[“a”]

    • 读取第三个部分:“.”
      当前目录,忽略。
      stack:[“a”]

    • 读取第四个部分:“b”
      将 “b” 压入
      stack:[“a”, “b”]

    • 读取第五个部分:“…”
      返回上一级目录,弹出顶元素 “b”。
      stack:[“a”]

    • 读取第六个部分:“…”
      返回上一级目录,弹出顶元素 “a”。
      stack:[]

    • 读取第七个部分:“c”
      将 “c” 压入
      stack:[“c”]

  • 构建简化后的路径
    初始化 simplified:“”
    遍历中的每个目录,将其添加到 simplified 字符串中,并在每个目录前加上 /。
    simplified:“/c”

  • 返回结果
    simplified 不为空,返回 “/c”

  • 最终结果
    简化后的路径为:“/c”

  1. c++ 完整demo
#include string"><iostream>
#include string"><vector>
#include string"><string>
#include string"><sstream>class Solution {
public:std::string simplifyPath(std::string path) {std::vector<std::string> stack;//定义一个//创建了一个 std::stringstream 对象 ss,并将字符串 path 作为其初始内容。//这样做的目的是为了方便地对路径字符串进行分割和读取操作。std::stringstream ss(path);//dir 用于存储从 stringstream 中读取的每个目录std::string dir;//使用 getline 函数从 stringstream 中按 / 分割读取路径的每个部分,直到没有更多内容可读。while (getline(ss, dir, '/')) {//如果目录为空字符串或为 ".",表示当前目录,不做任何操作,继续下一次循环。if (dir.empty() || dir == string">".") {continue;}//如果目录为 "..",表示返回上一级目录。如果不为空,则弹出顶元素(即移除上一级目录)。else if (dir == string">"..") {if (!stack.empty()) {stack.pop_back();}}//否则,将该目录压入中。 else {stack.push_back(dir);}}//初始化一个空字符串 simplified,用于存储简化后的路径。然后遍历中的每个目录,//将其添加到 simplified 字符串中,并在每个目录前加上 /。std::string simplified;for (const std::string& d : stack) {simplified += string">"/" + d;}//simplified 为空字符串,说明路径简化后是一个根目录,返回 /。否则,返回 simplified。return simplified.empty() ? string">"/" : simplified;}
};int main() {Solution solution;std::string path = string">"/home//foo/";std::string simplifiedPath = solution.simplifyPath(path);std::cout << string">"Simplified Path: " << simplifiedPath << std::endl;return 0;
}

http://www.ppmy.cn/devtools/153051.html

相关文章

【docker-1】快速入门docker

docker搭建 1、下载二进制文件 wget https://mirror.nju.edu.cn/docker-ce/linux/static/stable/aarch64/docker-20.10.7.tgz解压docker目录 tar -xzvf docker-20.10.7.tgz .安装文件到/usr/local/bin mv ./docker/* /usr/local/bin2、配置docker.service [Unit] Descript…

在C#中添加I/O延时和持续时间

在C#中添加I/O延时和持续时间&#xff0c;可以通过以下方法实现。具体来说&#xff0c;延时可以通过Thread.Sleep、Task.Delay等方式来模拟延迟&#xff0c;而持续时间的控制可以通过循环结构来设定持续的时间。在执行I/O操作时&#xff0c;你可以在操作之间添加延时&#xff0…

【机器学习应用】预处理与特征工程

这里是阿川的博客&#xff0c;祝您变得更强 ✨ 个人主页&#xff1a;在线OJ的阿川 &#x1f496;文章专栏&#xff1a;机器学习应用入门到进阶 &#x1f30f;代码仓库&#xff1a;GitHub平台 写在开头 现在您看到的是我的结论或想法&#xff0c;但在这背后凝结了大量的思考、经…

重学设计模式-单例模式

一、什么是单例模式 单例模式&#xff0c;从字面意思理解&#xff0c;就是保证一个类只有一个实例&#xff0c;并提供一个全局访问点来访问这个实例。想象一下&#xff0c;在一个大型游戏中&#xff0c;游戏的配置信息类&#xff0c;整个游戏运行期间只需要一份配置数据就够了…

如何运用python爬虫获取大型资讯类网站文章,并同时导出pdf或word格式文本?

这里&#xff0c;我们以比较知名的商业新知网站https://www.shangyexinzhi.com/为例进行代码编写&#xff0c;下面进行代码应用思路。 第一部分&#xff0c;分析网站结构 首先&#xff0c;我们来分析&#xff0c;要使用Python技术分析一个网站的结构&#xff0c;通常可以通过…

使用 JMeter 的 Autostop Listener 插件:自动化性能测试的守护者

在性能测试中&#xff0c;监控测试执行的状态并及时做出响应是至关重要的。如果测试过程中出现性能瓶颈或系统崩溃&#xff0c;继续运行测试可能会导致资源浪费或测试结果不准确。JMeter 的 Autostop Listener 插件正是为了解决这一问题而设计的。它允许你设置自动化停止条件&a…

【Ubuntu】安装SSH启用远程连接

【Ubuntu】安装OpenSSH启用远程连接 零、安装软件 使用如下代码安装OpenSSH服务端&#xff1a; sudo apt install openssh-server壹、启动服务 使用如下代码启动OpenSSH服务端&#xff1a; sudo systemctl start ssh贰、配置SSH&#xff08;可跳过&#xff09; 配置文件 …

两两交换链表中的节点

给定一个链表&#xff0c;两两交换其中相邻的节点&#xff0c;并返回交换后的链表。 思路 这道题目正常模拟就行了。//我还不熟练如何模拟&#xff0c;我在这方面还是差了点&#xff0c;毕竟还算是新手。所有链表都建议使用虚拟头结点。 ListNode *swap(ListNode *head) {Lis…