算法初探LeetCode-简化路径

86 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第4天,点击查看活动详情

LeetCode71:简化路径

给你一个字符串 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 风格绝对路径。

思路分析

分析题目可用栈结构来解题

将路径通过 / 分开各个目录(忽略连续 /),然后讨论不同目录的情况:

  • 对于目录 . ,不操作
  • 对于目录 .. ,则进行出栈,回到上一层目录,如果是上一级目录是根目录则不出栈
  • 对于其它目录,则进行入栈

然后遍历栈,将它们连接起来返回。

算法代码

public String simplifyPath(String path) {
    Deque < String > stack = new ArrayDeque < > ();
    stack.push("/");
    int n = path.length();
    int r = 1;
    while (r < n) {
        if (path.charAt(r++) == '/') continue;
        int l = r - 1;
        while (r < n && path.charAt(r) != '/') r++;
        String name = path.substring(l, r);
        if (name.equals("..")) {
            if (stack.size() > 1) stack.pop();
        } else if (!name.equals(".")) {
            stack.push(name);
        }
    }
    StringBuilder builder = new StringBuilder();
    int size = stack.size();
    for (int i = 0; i < size; i++) {
        builder.append(stack.pollLast());
        if (i != 0 && i != size - 1) builder.append('/');
    }
    return builder.toString();
}

结果

111.png

算法复杂度

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

掘金(JUEJIN)一起进步,一起成长!