【力扣时间】【71】【中等】简化路径

好消息是,这题我刷过。
坏消息是,太久了我完全忘了。

1、看题先

我是题

点开今天的每日一题,发现已经完成时,我是一脸蒙蔽的。
愣了会才想起来,编号较小,可能之前我就已经刷到过了。

2、审题

题目罗里吧嗦,但提炼出来,就是一个栈的问题。
而对于遇到的路径命令,我们只需要遵循以下操作:

  1. 遇到.无视
  2. 遇到..返回上一级
  3. 遇到其他名称,进入该目录
  4. 遇到 // 无视

3、思路

简单扫了下题目后,曾经的思路就慢慢在脑海里浮现

很显然,我们只需要用到栈的思想,将所有需要进入的目录入栈,在遇到 .. 后将栈顶的目录出栈,以表示返回。
其他情况不做任何考虑,然后留在栈内的数据即为最终的路径。

4、动手

class Solution {
     private static String DOT = ".";

    private static String DOUBLE_DOT = "..";

    public String simplifyPath(String path) {
        String[] splits = path.split("/");

        Stack<String> stack = new Stack<>();
        for (String s : splits) {
            //单点不做任何处理
            if (s.equals("") || s.equals(DOT)) {
                continue;
            }

            if (s.equals(DOUBLE_DOT)) {
                //遇上双点时,将栈顶的元素出栈
                if (!stack.isEmpty()) {
                    stack.pop();
                }
            } else {
                //遇上其他时,压入栈内
                stack.push(s);
            }
        }

        //压入新栈以反转整个栈
        Stack<String> otherStack = new Stack<>();
        while (!stack.isEmpty()) {
            otherStack.push(stack.pop());
        }

        //再将新栈出栈来构建地址
        StringBuilder sb = new StringBuilder();
        while (!otherStack.isEmpty()) {
            sb.append("/");
            String s = otherStack.pop();
            sb.append(s);
        }

        //空地址时,返回/
        if (sb.length() == 0) {
            sb.append("/");
        }

        return sb.toString();
    }
}

5、解读

首先,这里犯了个小蠢。在第一次的提交中,我直接将路径顺序按出栈顺序拼接,然后发现顺序倒了。
于是,要将栈内的数据反转过来,怎么办呢?大学C语言老师的教诲浮现在脑海——再拿个栈来,将前一个栈的数据依次出栈,再依次压入新栈内,最后新栈再依次出栈,顺序就翻转了。
然后就出现了这么个不伦不类的东西……

好吧,一点点来。
首先我们以/拆分字符串,这样就可以拿到/间的所有字符,而不用处理遇到///的情况。
之后,就如同我先前将的,.无视,..出栈,其他字符入栈即可。

Stack<String> stack = new Stack<>();
for (String s : splits) {
    //单点不做任何处理
    if (s.equals("") || s.equals(DOT)) {
        continue;
    }

    if (s.equals(DOUBLE_DOT)) {
        //遇上双点时,将栈顶的元素出栈
        if (!stack.isEmpty()) {
            stack.pop();
        }
    } else {
        //遇上其他时,压入栈内
        stack.push(s);
    }
}

然后,就是翻转栈内的数据了……
拿个新栈接一下旧栈出栈的数据。

//压入新栈以反转整个栈
Stack<String> otherStack = new Stack<>();
while (!stack.isEmpty()) {
    otherStack.push(stack.pop());
}

最后以StringBuilder拼接字符串并返回,万事大吉。

注意如果栈为空,没有路径时,要返回/

6、提交

在这里插入图片描述

7、咀嚼

虽然遍历了多次,但不涉及到嵌套,时间复杂度为O(N)
然后,使用了栈来存储所有字符信息,空间复杂度也为O(N)

8、看看大牛

实际上,今天大牛们也没有什么花样,思路都是我这一样的。
不过,看了大牛的题解才发现我这那两个栈来翻转数据的做法是真的蠢。
特别是java api有提供双向队列Deque,既能让你从尾部做出栈操作,也能让你从头部直接获取数据,十分切合此题。

高级语言的api就是你最好的算法助手!
前提当然是你得知道并且会用它们。

9、总结

这是坚持刷每日一题以来,第一次刷到之前就已经做过的题。
现在回想起之前的青涩的岁月,真是感慨万千啊……

然而最让我感慨是为什么我还是辣么的菜!

周四了,虽然你可能才上三天班,但今天确实是周四了!
努力努力,明天周五后又可以休假了。

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值