Leetcode 简化路径

在这里插入图片描述

算法思想:简化路径

这段代码的目标是将给定的Unix风格的路径字符串简化为标准化的路径。以下是算法的详细解释:


1. 使用栈来模拟路径导航

  • 栈(Stack) 是一个先进后出的数据结构,可以很好地模拟路径的导航过程。例如:
    • 遇到 .. 表示回到上一级目录,我们可以通过弹出栈的顶部元素(回退到上一级目录)。
    • 遇到正常的目录名时,入栈,表示进入该目录。
    • 遇到 . 或空字符串时,表示当前目录或者无意义字符,不需要任何操作。

2. 将路径分割成组件

使用 String.split("/") 方法,将输入路径根据斜杠 / 分割成若干部分。例如:

  • 输入路径 /a/./b/../../c/ 会被分割为:
    ["", "a", ".", "b", "..", "..", "c", ""]
  • 通过遍历这些分割后的组件,我们逐步简化路径。

3. 遍历路径组件并处理规则

在遍历每个组件时,依据以下规则处理:

  • 忽略无意义的部分
    • 空字符串 "" 和单点 . 表示当前目录,不需要任何操作,直接跳过。
  • 处理双点 ..
    • 表示返回上一级目录。如果栈不为空,弹出栈顶元素(即从当前路径返回上一级目录)。
    • 如果栈为空,说明已经在根目录,.. 不会进一步影响路径。
  • 处理有效目录名
    • 如果是普通的目录名(例如 ab),将其压入栈中,表示进入该目录。

4. 重建简化后的路径

当所有组件处理完毕后,栈中保存的是简化路径的每一级目录。将栈中的目录从底到顶依次用 / 拼接起来,形成最终的结果。

  • 如果栈为空(例如输入路径是 /../),返回根目录 /

代码中的逻辑分步解释

(1) 初始化栈与分割路径
Deque<String> stack = new LinkedList<>();
String[] components = path.split("/");
  • 使用栈来记录路径。
  • 将路径分割为目录名的数组,便于逐一处理。
(2) 遍历路径组件
for (String component : components) {
    if (component.equals("") || component.equals(".")) {
        continue; // 忽略空字符串和"."
    } else if (component.equals("..")) {
        if (!stack.isEmpty()) {
            stack.pop(); // 返回上一级目录
        }
    } else {
        stack.push(component); // 入栈有效目录名
    }
}
  • 遍历每个分割的路径组件,按照规则进行处理。
  • 忽略无意义的部分,遇到 .. 时弹栈,遇到普通目录名时入栈。
(3) 重建路径
StringBuilder result = new StringBuilder();
for (String dir : stack) {
    result.insert(0, "/" + dir); // 从栈底到栈顶拼接路径
}
return result.length() > 0 ? result.toString() : "/";
  • 从栈中逐一取出元素,拼接成简化路径。
  • 如果栈为空,说明路径已经简化到根目录 /

5. 测试用例的解释

  • 用例 1:

    simplifyPath("/home/")
    

    处理过程:

    • 分割为:["", "home", ""]
    • 栈操作:push("home")
    • 重建路径:/home
  • 用例 2:

    simplifyPath("/../")
    

    处理过程:

    • 分割为:["", "..", ""]
    • 栈为空时遇到 ..,保持不变
    • 重建路径:/
  • 用例 3:

    simplifyPath("/a/./b/../../c/")
    

    处理过程:

    • 分割为:["", "a", ".", "b", "..", "..", "c", ""]
    • 栈操作:
      1. push("a")
      2. 忽略 .
      3. push("b")
      4. 遇到 ..,弹出 "b"
      5. 遇到 ..,弹出 "a"
      6. push("c")
    • 重建路径:/c

6. 算法复杂度分析

  • 时间复杂度: ( O(n) )

    • 分割字符串的复杂度为 ( O(n) ),每个路径组件遍历一次。
    • 栈的入栈和出栈操作平均为 ( O(1) )。
  • 空间复杂度: ( O(n) )

    • 使用栈存储路径组件,最坏情况下栈中存储所有有效目录名。

总结

这段代码通过栈巧妙地处理路径简化问题,遵循了Unix风格路径的规则,能够有效地处理各种边界情况,是一种简洁高效的实现方式。

java 实现

class Solution {
    public String simplifyPath(String path) {
        Deque<String> stack = new LinkedList<>(); //Deque是双端队列
        String[] components = path.split("/");
        for(String component : components) {
            if(component.equals(".") || component.equals("")) {
                continue;   
            } else if(component.equals("..")) {
                if(!stack.isEmpty()) {
                    stack.pop();
                }
            } else {
                stack.push(component);  
            }
        }
        
        StringBuilder result = new StringBuilder();
        for(String dir:stack) {
            result.insert(0, "/" + dir); //0是偏移量,在字符串最左端插入
        }
        return result.length() > 0 ? result.toString() : "/";
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值