27

力扣71——简化路径

 4 years ago
source link: http://mp.weixin.qq.com/s?__biz=MzU0NTk3NDMyMQ%3D%3D&%3Bmid=2247483896&%3Bidx=1&%3Bsn=ddf51be36f5ae51b8f8a9fbcd3bbde35
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

原题

以 Unix 风格给出一个文件的绝对路径,你需要简化它。或者换句话说,将其转换为规范路径。

在 Unix 风格的文件系统中,一个点(.)表示当前目录本身;此外,两个点 (..) 表示将目录切换到上一级(指向父目录);两者都可以是复杂相对路径的组成部分。更多信息请参阅:Linux / Unix中的绝对路径 vs 相对路径

请注意,返回的规范路径必须始终以斜杠 / 开头,并且两个目录名之间必须只有一个斜杠 /。最后一个目录名(如果存在)不能以 / 结尾。此外,规范路径必须是表示绝对路径的最短字符串。

示例 1:

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

示例 2:

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

示例 3:

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

示例 4:

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

示例 5:

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

示例 6:

输入:"/a//b////c/d//././/.."
输出:"/a/b/c"

原题url:https://leetcode-cn.com/problems/simplify-path/

解法

看起也不难,但一开始我拿到的时候也是无从下手。

利用栈

看到 .. 的逻辑就特别容易让人想到后退,而记录后退最方便的数据结构应该就是 了。至于 . 就可以想象成可以忽略的内容,而 / 则可以作为分隔符了,来看看代码:

class Solution {
    public String simplifyPath(String path) {
        // 存储路径
        Stack<String> stack = new Stack<>();

                // 分隔
        String[] array = path.split("/");
        for (String str : array) {
                        // 忽略
            if (str.equals("") || str.equals(".")) {
                continue;
            }

                        // 后退
            if (str.equals("..")) {
                stack.pop();
                continue;
            }

                        // 需要存储的内容
            stack.push(str);
        }

        StringBuilder sb = new StringBuilder();
        for (String str : stack) {
            sb.append("/").append(str);
        }
                // 如果内容为空,则需要输出"/"
        if (sb.length() == 0) {
            sb.append("/");
        }
        return sb.toString();
    }
}

看起来很美好,提交之后报错了。说是 stack.push(str); 这行抛出了异常 java.util.EmptyStackException ,确实,如果栈为空,依旧还是需要在最顶层的(看来还是没有把问题想全面)。让我们来优化一下代码:

class Solution {
    public String simplifyPath(String path) {
        // 存储路径
        Stack<String> stack = new Stack<>();

                // 分隔
        String[] array = path.split("/");
        for (String str : array) {
                        // 忽略
            if (str.equals("") || str.equals(".")) {
                continue;
            }

                        // 后退
            if (str.equals("..")) {
                            // 判断是否为空,不为空,才需要回退
                if (!stack.empty()) {
                    stack.pop();
                }
                                // 无论stack空不空,都需要结束
                continue;
            }

            stack.push(str);
        }

        StringBuilder sb = new StringBuilder();
        for (String str : stack) {
            sb.append("/").append(str);
        }
        if (sb.length() == 0) {
            sb.append("/");
        }
        return sb.toString();
    }
}

OK,通过了,执行用时: 6ms ,内存消耗: 36.2MB

总结

以上就是这道题目我的解答过程了,不知道大家是否理解了。因为之前已经刷了一些题目了,所以会把这些解题过程都补上去,也当做复习了。我刷题都是选 medium 的,所以不会很难,主要我看外企的面试大多也是以这样的题目为主,刷 hard 的题目确实感觉太费脑子,打击积极性。希望能与大家共同进步。

有兴趣的话可以访问我的博客或者关注我的公众号、头条号,说不定会有意外的惊喜。

https://death00.github.io/

公众号:健程之道

r2QvuaF.jpg!web

6fUnyy2.jpg!web


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK