zoukankan      html  css  js  c++  java
  • 力扣71——简化路径

    原题

    以 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/

    公众号:健程之道

  • 相关阅读:
    JAVA实现接口监控报警系统
    批量插入数据、自定义分页器
    django与Ajax
    ORM优化查询、choices参数
    django之查询操作及开启事务
    django之ORM字段及参数
    数据库设计
    django之模型层
    django之模板层
    django之视图层
  • 原文地址:https://www.cnblogs.com/death00/p/12081292.html
Copyright © 2011-2022 走看看