LeetCode 71:简化路径

一、题目描述

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

在 Unix 风格的文件系统中,一个点(.)表示当前目录本身;此外,两个点 (..) 表示将目录切换到上一级(指向父目录);两者都可以是复杂相对路径的组成部分。任意多个连续的斜杠(即,'//')都被视为单个斜杠 '/' 。 对于此问题,任何其他格式的点(例如,'...')均被视为文件/目录名称。

请注意,返回的 规范路径 必须遵循下述格式:

  • 始终以斜杠 '/' 开头。
  • 两个目录名之间必须只有一个斜杠 '/' 。
  • 最后一个目录名(如果存在)不能 以 '/' 结尾。
  • 此外,路径仅包含从根目录到目标文件或目录的路径上的目录(即,不含 '.' 或 '..')。

返回简化后得到的 规范路径 。

示例 1:

输入:path = "/home/"
输出:"/home"
解释:注意,最后一个目录名后面没有斜杠。 

示例 2:

输入:path = "/../"
输出:"/"
解释:从根目录向上一级是不可行的,因为根目录是你可以到达的最高级。

示例 3:

输入:path = "/home//foo/"
输出:"/home/foo"
解释:在规范路径中,多个连续斜杠需要用一个斜杠替换。

示例 4:

输入:path = "/a/./b/../../c/"
输出:"/c"

提示:

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

二、思路分析

我们将给定的字符串 path 根据 "/" 分割成字符串的列表。

根据题目可知,字符串数组包含的字符串只有以下几种:

1、空字符串。例如当出现多个连续的 /,就会分割出空字符串;

2、一个点 ".";

3、两个点 "..";

4.只包含英文字母、数字或 _ 的目录名;

对于 空字符串 以及 ".",我们实际上无需对它们进行处理,因为 空字符串 没有意义,而 "." 表示当前目录本身,我们无需切换目录。

对于 ".." 或者 目录名,我们则可以用一个 双端队列 来记录路径中的每一个目录名。当我们遇到 ".." 时,需要将目录切换到上一级,因此只要 列表 不为空,我们就弹出 队列 的目录。当我们遇到目录名时,就把它放入列表。

这样一来,我们只需要遍历字符数组中的每个字符串并进行上述操作即可。在所有的操作完成后,我们将列表最前面到最后的字符串用 "/" 进行连接,再在最前面加上 "/" 表示根目录,就可以得到简化后的规范路径。

三、代码参考

1、Java

class Solution {
    public String simplifyPath(String path) {
        // 将 path 路径根据 / 进行分割
        String[] paths = path.split("/");
        // 创建双端队列用于存放
        Deque deque = new ArrayDeque<>();
        // 遍历 paths 字符数组
        for(String p : paths){
            if("..".equals(p)){
                // 如果字符是 .. 代表回到上一级目录
                if(!deque.isEmpty()){
                    // 如果队列不为空,则移除最后一个字符,即一个路径
                    deque.pollLast();
                }
            }
            // 如果目录名字符长度大于零,且不是字符 ".",则把字符添加到列表尾部
            else if(p.length() > 0 && !".".equals(p)){
                // 将元素添加到列表尾部
                deque.offerLast(p);
            }
        }
        // 创建 StringBuffer 对象,用来拼接字符串路径
        StringBuffer strPath = new StringBuffer();
        // 如果双端队列 deque 已经为空,则直接返回 "/" 就好
        if(deque.isEmpty()){
            strPath.append("/");
        }
        // 如果不为空,则将里面的字符全部取出拼接成路径返回
        else {
            // 循环获取 deque 里面的所有字符
            while(!deque.isEmpty()){
                // 先添加 "/" ,因为以 "/" 开始
                strPath.append("/");
                // 获取第一个元素并移除,从第一个元素开始构建路径
                strPath.append(deque.pollFirst());
            }
        }
        // 返回路径结果
        return strPath.toString();
    }
}

2、Python3

class Solution:
    def simplifyPath(self, path: str) -> str:
        # 分割字符串为列表形式
        names = path.split("/")

        # 利用栈来处理
        stack = list()

        # 访问列表里面的元素
        for name in names:
            print(name)
            # 1、如果是 .. 
            if name == "..":
                # 在栈不为空的情况下
                if stack:
                    # 弹出栈顶元素
                    stack.pop()
            # 2、如果是有效值
            # 字母
            elif name and name != ".":
                stack.append(name)
        # 我们使用/ 作为分隔符,将栈stack中的元素连接成一个新的字符串。
        # 每个元素之间使用/ 进行分隔,因此输出结果中每个元素都以/ 结尾(除了最后一个元素)。
        return "/" + "/".join(stack)

你可能感兴趣的:(数据结构与算法,leetcode,算法,数据结构,java,python)