LeetCode——1233. 删除子文件夹

文章介绍了一个系统管理员的任务,即删除文件夹列表中的所有子文件夹并返回剩余文件夹。解决方案是先对文件夹进行排序,然后逐个检查文件夹,通过比较前缀来判断是否为子文件夹。代码实现中涉及字符串操作和时间复杂度分析,主要时间消耗在排序上。

一、题目

你是一位系统管理员,手里有一份文件夹列表 folder,你的任务是要删除该列表中的所有子文件夹,并以任意顺序返回剩下的文件夹。

如果文件夹 folder[i] 位于另一个文件夹 folder[j] 下,那么 folder[i] 就是 folder[j] 的 子文件夹 。

文件夹的「路径」是由一个或多个按以下格式串联形成的字符串:‘/’ 后跟一个或者多个小写英文字母。

例如,“/leetcode” 和 “/leetcode/problems” 都是有效的路径,而空字符串和 “/” 不是。
在这里插入图片描述
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/remove-sub-folders-from-the-filesystem/description/

二、C解法

我的思路及代码

首先对文件夹进行排序,这样字母靠前的文件会在前面,这样第一个文件夹必然是父文件夹,直接存入我们的答案中,然后遍历文件夹,分为两步:

  1. 对遇到的每一个文件夹进行前缀比对(这个前缀就是我们上一次存入答案数组的文件夹字符串)
  2. 判断前缀匹配后的下一个字符是不是 ‘/’ 防止出现这样的情况:前缀为 “/a/a” 待匹配的文件夹字符串为 “/a/ab” 此时只判断前缀是可以匹配成功的,但是此文件夹并不是前面的子文件。

两步都成功全部匹配成功则说明当前文件是属于子文件,有一步失败则说明此文件是父级文件,则添加进答案即可。

class Solution {
public:
    vector<string> removeSubfolders(vector<string>& folder) {
        sort(folder.begin(),folder.end());
        vector<string> ans;
        ans.push_back(folder[0]);
        for(int i=1;i<folder.size();i++){
            if(ans[ans.size()-1]!=folder[i].substr(0, ans[ans.size()-1].size())||folder[i][ans[ans.size()-1].size()]!='/'){
                ans.push_back(folder[i]);
            }
        }
        return ans;
    }
};
  • 时间复杂度:时间复杂度:O(nl⋅log⁡n),其中 n 和 l 分别是数组 folder 的长度和文件夹的平均长度。O(nl⋅log⁡n)为排序需要的时间,后续构造答案需要的时间为 O(nl),在渐进意义下小于前者。
  • 空间复杂度:空间复杂度:O(l)。在构造答案比较前缀时,我们使用了字符串的截取子串操作,因此需要 O(l) 的临时空间。我们也可以使用一个递增的指针依次对两个字符串的每个相同位置进行比较,省去这一部分的空间,使得空间复杂度降低至排序需要的栈空间 O(log⁡n)。但空间优化并不是本题的重点,因此上述的代码中仍然采用空间复杂度为 O(l) 的写法。注意这里不计入返回值占用的空间。

官方参考代码

思路和我差不多,但是写法很高级,随便看看吧

class Solution {
public:
    vector<string> removeSubfolders(vector<string>& folder) {
        sort(folder.begin(), folder.end());
        vector<string> ans = {folder[0]};
        for (int i = 1; i < folder.size(); ++i) {
            if (int pre = ans.end()[-1].size(); !(pre < folder[i].size() && ans.end()[-1] == folder[i].substr(0, pre) && folder[i][pre] == '/')) {
                ans.push_back(folder[i]);
            }
        }
        return ans;
    }
};
  • 时间复杂度:时间复杂度:O(nl⋅log⁡n),其中 n 和 l 分别是数组 folder 的长度和文件夹的平均长度。O(nl⋅log⁡n)为排序需要的时间,后续构造答案需要的时间为 O(nl),在渐进意义下小于前者。
  • 空间复杂度:空间复杂度:O(l)。在构造答案比较前缀时,我们使用了字符串的截取子串操作,因此需要 O(l) 的临时空间。我们也可以使用一个递增的指针依次对两个字符串的每个相同位置进行比较,省去这一部分的空间,使得空间复杂度降低至排序需要的栈空间 O(log⁡n)。但空间优化并不是本题的重点,因此上述的代码中仍然采用空间复杂度为 O(l) 的写法。注意这里不计入返回值占用的空间。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

天地神仙

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

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

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

打赏作者

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

抵扣说明:

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

余额充值