leetcode 面試經典 150 題:簡化路徑

鏈接簡化路徑
題序號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 == ".") {continue;}//如果目錄為 "..",表示返回上一級目錄。如果棧不為空,則彈出棧頂元素(即移除上一級目錄)。else if (dir == "..") {if (!stack.empty()) {stack.pop_back();}}//否則,將該目錄壓入棧中。 else {stack.push_back(dir);}}//初始化一個空字符串 simplified,用于存儲簡化后的路徑。然后遍歷棧中的每個目錄,//將其添加到 simplified 字符串中,并在每個目錄前加上 /。std::string simplified;for (const std::string& d : stack) {simplified += "/" + d;}//simplified 為空字符串,說明路徑簡化后是一個根目錄,返回 /。否則,返回 simplified。return simplified.empty() ? "/" : 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 <iostream>
#include <vector>
#include <string>
#include <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 == ".") {continue;}//如果目錄為 "..",表示返回上一級目錄。如果棧不為空,則彈出棧頂元素(即移除上一級目錄)。else if (dir == "..") {if (!stack.empty()) {stack.pop_back();}}//否則,將該目錄壓入棧中。 else {stack.push_back(dir);}}//初始化一個空字符串 simplified,用于存儲簡化后的路徑。然后遍歷棧中的每個目錄,//將其添加到 simplified 字符串中,并在每個目錄前加上 /。std::string simplified;for (const std::string& d : stack) {simplified += "/" + d;}//simplified 為空字符串,說明路徑簡化后是一個根目錄,返回 /。否則,返回 simplified。return simplified.empty() ? "/" : simplified;}
};int main() {Solution solution;std::string path = "/home//foo/";std::string simplifiedPath = solution.simplifyPath(path);std::cout << "Simplified Path: " << simplifiedPath << std::endl;return 0;
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/67015.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/67015.shtml
英文地址,請注明出處:http://en.pswp.cn/web/67015.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

如何在gitee/github上面搭建obsidian的圖床

在搭建圖床之前我們需要知道圖床是一個什么東西,圖床顧名思義就是存放圖片的地方&#xff0c;那么我們為什么要搭建圖床呢&#xff1f;因為我們在寫博客的時候&#xff0c;很多同學都是在本地使用typora或者是obsidian進行markdown語法的文章的書寫&#xff0c;文件格式通常都是…

JVM堆空間

JVM&#xff08;Java虛擬機&#xff09;堆空間是Java內存管理的核心區域之一&#xff0c;用于存儲Java對象實例。以下是關于JVM堆空間的詳細介紹&#xff1a; 1. 堆空間的作用 ? 存儲對象實例&#xff1a;幾乎所有的Java對象實例&#xff08;通過new關鍵字創建的對象&#xf…

Redis 的熱 Key(Hot Key)問題及解決方法

Redis 的熱 Key&#xff08;Hot Key&#xff09;問題及解決方法 1. 什么是 Redis 熱 Key&#xff1f; Redis 熱 Key&#xff08;Hot Key&#xff09;指的是訪問頻率極高的 Key&#xff0c;通常會造成以下問題&#xff1a; 單 Key 訪問量過大&#xff1a;熱點 Key 可能被高并…

SSM東理咨詢交流論壇

&#x1f345;點贊收藏關注 → 添加文檔最下方聯系方式咨詢本源代碼、數據庫&#x1f345; 本人在Java畢業設計領域有多年的經驗&#xff0c;陸續會更新更多優質的Java實戰項目希望你能有所收獲&#xff0c;少走一些彎路。&#x1f345;關注我不迷路&#x1f345; 項目視頻 js…

http的請求體各項解析

一、前言 做Java開發的人員都知道&#xff0c;其實我們很多時候不單單在寫Java程序。做的各種各樣的系統&#xff0c;不管是PC的 還是移動端的&#xff0c;還是為別的系統提供接口。其實都離不開http協議或者https 這些東西。Java作為編程語言&#xff0c;再做業務開發時&#…

gradle生命周期鉤子函數

文章目錄 0. 總結表格1. 構建初始階段gradle.settingsEvaluated()gradle.projectsLoaded() 2. 配置階段gradle.beforeProject()gradle.afterProject()gradle.projectEvaluated()gradle.afterEvaluate()gradle.taskGraph.whenReady 3. 執行階段gradle.taskGraph.beforeTaskgradl…

Qt Enter和HoverEnter事件

介紹 做PC開發的過程中或多或少都會接觸到鼠標的懸停事件&#xff0c;Qt中處理鼠標懸停有Enter和HoverEnter兩種事件 相同點 QEvent::Enter對應QEnterEvent&#xff0c;描述的是鼠標進入控件坐標范圍之內的行為&#xff0c;QEnterEvent可以抓取鼠標的位置&#xff1b;QEvent…

【云安全】云原生-Docker(五)容器逃逸之漏洞利用

漏洞利用逃逸 通過漏洞利用實現逃逸&#xff0c;主要分為以下兩種方式&#xff1a; 1、操作系統層面的內核漏洞 這是利用宿主機操作系統內核中的安全漏洞&#xff0c;直接突破容器的隔離機制&#xff0c;獲得宿主機的權限。 攻擊原理&#xff1a;容器本質上是通過 Linux 的…

如何優化深度學習模型來提高錯別字檢測準確率?

為了優化深度學習模型以提高錯別字檢測的準確率,可以從以下幾個方面入手: 1. 數據增強 數據增強是提高模型泛化能力的有效方法。通過在訓練數據中引入噪聲,模型可以學習到更多變的模式,從而提高對未見數據的識別能力。 刪除字符:以一定概率刪除文本中的一個字符。增加字…

二叉搜索樹中的搜索(力扣700)

首先介紹一下什么是二叉搜索樹。 二叉搜索樹是一個有序樹&#xff1a; 若它的左子樹不空&#xff0c;則左子樹上所有結點的值均小于它的根結點的值&#xff1b;若它的右子樹不空&#xff0c;則右子樹上所有結點的值均大于它的根結點的值&#xff1b;它的左、右子樹也分別為二叉…

pytest自動化測試 - 構造“預置條件”的幾種方式

<< 返回目錄 1 pytest自動化測試 - 構造“預置條件”的幾種方式 1.1 使用夾具構造預置條件 在夾具章節中&#xff0c;我們介紹了夾具的作用&#xff0c;其中一項就是構造預置條件。pytest.fixture裝飾器中如果測試數據使用yield返回&#xff0c;則yield前的語句為預置條…

微信小程序date picker的一些說明

微信小程序的picker是一個功能強大的組件&#xff0c;它可以是一個普通選擇器&#xff0c;也可以是多項選擇器&#xff0c;也可以是時間、日期、省市區選擇器。 官方文檔在這里 這里講一下date picker的用法。 <view class"section"><view class"se…

[java] 面向對象進階篇1--黑馬程序員

目錄 static 靜態變量及其訪問 實例變量及其訪問 靜態方法及其訪問 實例方法及其訪問 總結 繼承 作用 定義格式 示例 總結 子類不能繼承的內容 繼承后的特點 成員變量 成員變量不重名 成員變量重名 super訪問父類成員變量 成員方法 成員方法不重名 成員方法…

python3+TensorFlow 2.x 基礎學習(一)

目錄 TensorFlow 2.x基礎 1、安裝 TensorFlow 2.x 2、TensorFlow 2.x 基礎概念 2、1 Eager Execution 2、2 TensorFlow 張量&#xff08;Tensor&#xff09; 3、使用Keras構建神經網絡模型 3、1 構建 Sequential 模型 3、2 編譯模型 1、Optimizer&#xff08;優化器&a…

AI News(1/21/2025):OpenAI 安全疏忽:ChatGPT漏洞引發DDoS風險/OpenAI 代理工具即將發布

1、OpenAI 的安全疏忽&#xff1a;ChatGPT API 漏洞引發DDoS風險 德國安全研究員 Benjamin Flesch 發現了一個嚴重的安全漏洞&#xff1a;攻擊者可以通過向 ChatGPT API 發送一個 HTTP 請求&#xff0c;利用 ChatGPT 的爬蟲對目標網站發起 DDoS 攻擊。該漏洞源于 OpenAI 在處理…

openlava/LSF 用戶組管理腳本

背景 在openlava運維中經常需要自動化一些常規操作&#xff0c;比如增加用戶組以及組成員、刪除用戶組成員、刪除用戶組等。而openlava的配置文件需要手動修改&#xff0c;然后再通過badmin reconfig激活配置。因此開發腳本將手工操作自動化就很有必要。 通過將腳本中的User…

LLMs的星辰大海:大語言模型的前世今生

文章目錄 一. LLM 的演進&#xff1a;從規則到智能的躍遷 &#x1f4ab;1.1 語言模型的蹣跚起步 &#x1f476;1.2 RNN 與 LSTM&#xff1a;序列建模的嘗試 &#x1f9d0;1.3 Transformer 的橫空出世&#xff1a;自注意力機制的革命 &#x1f4a5;1.4 LLM &#xff1a;從預測到…

7-Zip高危漏洞CVE-2025-0411:解析與修復

7-Zip高危漏洞CVE-2025-0411&#xff1a;解析與修復 免責聲明 本系列工具僅供安全專業人員進行已授權環境使用&#xff0c;此工具所提供的功能只為網絡安全人員對自己所負責的網站、服務器等&#xff08;包括但不限于&#xff09;進行檢測或維護參考&#xff0c;未經授權請勿利…

數據結構(精講)----樹(應用篇)

特性&#xff1a; 什么是樹&#xff1a; 樹(Tree)是(n>0)個節點的有限集合T&#xff0c;它滿足兩個條件&#xff1a; (1) 有且僅有一個特定的稱為根&#xff08;Root&#xff09;的節點。 (2) 其余的節點可以分為m&#xff08;m≥0&#xff09;個互不相交的有限集合T1、…

【動態規劃】--- 斐波那契數模型

Welcome to 9ilks Code World (??? ? ???) 個人主頁: 9ilk (??? ? ???) 文章專欄&#xff1a; 算法Journey &#x1f3e0; 第N個泰波那契數模型 &#x1f4cc; 題目解析 第N個泰波那契數 題目要求的是泰波那契數&#xff0c;并非斐波那契數。 &…