栈题目:文件夹操作日志搜集器

题目

标题和出处

标题:文件夹操作日志搜集器

出处:1598. 文件夹操作日志搜集器

难度

2 级

题目描述

要求

每当用户执行变更文件夹操作时,LeetCode 文件系统都会保存一条日志记录。

下面给出对变更操作的说明:

  • "../" \texttt{"../"} "../":移动到当前文件夹的父文件夹。如果已经在主文件夹下,则继续停留在当前文件夹
  • "./" \texttt{"./"} "./":继续停留在当前文件夹。
  • "x/" \texttt{"x/"} "x/":移动到名为 x \texttt{x} x 的子文件夹中。题目数据保证总是存在文件夹 x \texttt{x} x

给你一个字符串列表 logs \texttt{logs} logs,其中 logs[i] \texttt{logs[i]} logs[i] 是用户在第 i \texttt{i} i 步执行的操作。

文件系统启动时位于主文件夹,然后执行 logs \texttt{logs} logs 中的操作。

执行完所有变更文件夹操作后,请你找出返回主文件夹所需的最小步数

示例

示例 1:

示例 1

输入: logs   =   ["d1/","d2/","../","d21/","./"] \texttt{logs = ["d1/","d2/","../","d21/","./"]} logs = ["d1/","d2/","../","d21/","./"]
输出: 2 \texttt{2} 2
解释:执行 "../" \texttt{"../"} "../" 操作变更文件夹 2 \texttt{2} 2 次,即可回到主文件夹。

示例 2:

示例 2

输入: logs   =   ["d1/","d2/","./","d3/","../","d31/"] \texttt{logs = ["d1/","d2/","./","d3/","../","d31/"]} logs = ["d1/","d2/","./","d3/","../","d31/"]
输出: 3 \texttt{3} 3

示例 3:

输入: logs   =   ["d1/","../","../","../"] \texttt{logs = ["d1/","../","../","../"]} logs = ["d1/","../","../","../"]
输出: 0 \texttt{0} 0

数据范围

  • 1 ≤ logs.length ≤ 10 3 \texttt{1} \le \texttt{logs.length} \le \texttt{10}^\texttt{3} 1logs.length103
  • 2 ≤ logs[i].length ≤ 10 \texttt{2} \le \texttt{logs[i].length} \le \texttt{10} 2logs[i].length10
  • logs[i] \texttt{logs[i]} logs[i] 包含小写英文字母,数字, ‘.’ \texttt{`.'} ‘.’ ‘/’ \texttt{`/'} ‘/’
  • logs[i] \texttt{logs[i]} logs[i] 符合语句中描述的格式
  • 文件夹名称由小写英文字母和数字组成

解法一

思路和算法

根据题目描述,每一步操作都是有效的操作,因此只要记录每一步操作之后所在的文件夹的路径,即可知道返回主文件夹所需的步数。文件夹的路径为从主文件夹到当前文件夹需要经过的全部文件夹。

可以使用栈记录文件夹的路径,栈顶元素为当前文件夹。

对于每种变更操作,分别对栈进行不同的操作:

  • “../" \text{``../"} “../":如果栈不为空,则将栈顶元素出栈,新的栈顶元素即为当前文件夹的父文件夹。如果栈为空,则不进行任何操作。
  • “./" \text{``./"} “./":不进行任何操作。
  • “x/" \text{``x/"} “x/":将 “x/" \text{``x/"} “x/" 入栈,新的栈顶元素即为名为 x \text{x} x 的子文件夹。

执行完所有变更文件夹操作后,如果栈不为空,则需要将栈内元素依次出栈,直到栈为空时,返回主文件夹,因此返回主文件夹所需的最小步数即为出栈次数。其实并不需要真正将元素出栈,出栈次数等同于栈内元素个数,栈内元素个数即为返回主文件夹所需的最小步数。

代码

class Solution {
    public int minOperations(String[] logs) {
        Deque<String> stack = new ArrayDeque<String>();
        int length = logs.length;
        for (int i = 0; i < length; i++) {
            String log = logs[i];
            if ("../".equals(log)) {
                if (!stack.isEmpty()) {
                    stack.pop();
                }
            } else if ("./".equals(log)) {
                continue;
            } else {
                stack.push(log);
            }
        }
        return stack.size();
    }
}

复杂度分析

  • 时间复杂度: O ( n ) O(n) O(n),其中 n n n 是数组 logs \textit{logs} logs 的长度。需要遍历数组 logs \textit{logs} logs 一次,这里假设数组 logs \textit{logs} logs 中的每个元素的长度都是常数。

  • 空间复杂度: O ( n ) O(n) O(n),其中 n n n 是数组 logs \textit{logs} logs 的长度。空间复杂度主要取决于栈空间,栈最多包含 n n n 个元素,这里假设数组 logs \textit{logs} logs 中的每个元素的长度都是常数。

解法二

思路和算法

由于返回主文件夹所需的最小步数只和栈内元素个数有关,而和元素内容无关,因此也可以不用栈,而是使用计数的方式计算返回主文件夹所需的最小步数。

具体做法是,使用 operations \textit{operations} operations 记录返回主文件夹所需的最小步数,初始时 operations = 0 \textit{operations} = 0 operations=0。出栈操作对应将 operations \textit{operations} operations 1 1 1,入栈操作对应将 operations \textit{operations} operations 1 1 1,任何时候 operations \textit{operations} operations 都是非负整数。执行完所有变更文件夹操作后, operations \textit{operations} operations 即为返回主文件夹所需的最小步数。

代码

class Solution {
    public int minOperations(String[] logs) {
        int operations = 0;
        int length = logs.length;
        for (int i = 0; i < length; i++) {
            String log = logs[i];
            if ("../".equals(log)) {
                operations = Math.max(operations - 1, 0);
            } else if ("./".equals(log)) {
                continue;
            } else {
                operations++;
            }
        }
        return operations;
    }
}

复杂度分析

  • 时间复杂度: O ( n ) O(n) O(n),其中 n n n 是数组 logs \textit{logs} logs 的长度。需要遍历数组 logs \textit{logs} logs 一次,这里假设数组 logs \textit{logs} logs 中的每个元素的长度都是常数。

  • 空间复杂度: O ( 1 ) O(1) O(1)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

伟大的车尔尼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值