简化路径

416 阅读3分钟

这是我参与2022首次更文挑战的第25天,活动详情查看:2022首次更文挑战

leetcode 简化路径

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

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

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

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

 

示例 1:

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

示例 2:

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

示例 3:

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

解题:可以利用栈来完成。目录之间是用一个斜杠/来分隔的,所以可以先将给定字符串path根据/符号来分段组成一个数组paths,然后我们分析paths数组的元素。path字符串是由英文字母,数字,'.','/' 或 ''组成,所以paths数组元素也都是英文字母,数字,'.','',或 '' 组成,因为是根据'/'分割所以,如果连续出现'/'那分割的时候就会用空字符串元素,那么对于空字符串''元素或者'.'一个点的元素就可以忽略,因为任意多个连续的斜杠'///'需要被视为单个斜杠'/',而单个点'.'的元素是表示当前目录。对于两个点'..'的元素代表要将目录切换到上一级,那具体的可以将paths数组的元素分为3类,第一类为空字符串''和单个点'.';第二类为两个点'..'代表切换到上一级;第三类就是其余字符的组合代表目录名。对此我们可以使用栈可以比较方便的处理,遍历paths数组当遇到空字符串''或者单个点'.'这些元素的时候就跳过本次循环,当遇到第三类元素时为一个目录名,就将该元素添加到栈里面,当遇到第二类元素要切换回上一级目录,在栈元素不为空的情况下,就取出一个栈元素来实现回到上级目录,如此反复操作直到遍历完paths数组元素,然后判断如果栈是空的就直接返回根目录'/',否则就循环从栈底取出元素拼接到斜杆'/'后面,最后返回即可。

class Solution {
    public String simplifyPath(String path) {
        Deque<String> stack = new ArrayDeque<String>();
        String[] paths = path.split("/");
        for (String str : paths) {
            if (str.length() == 0 || ".".equals(str)) {
                continue;
            }
            if ("..".equals(str)) {
                if (!stack.isEmpty()) {
                    stack.pollLast();
                }
                continue;
            }
            stack.offerLast(str);
        }
        if (stack.isEmpty()) {
            return "/";
        }
        StringBuilder res = new StringBuilder();
        while (!stack.isEmpty()) {
            res.append('/').append(stack.pollFirst());
        }
        return res.toString();
    }
}