LeetCode: 1233. Remove Sub-Folders from the Filesystem

Given a list of folders, remove all sub-folders in those folders and return in any order the folders after removing.
If a folder[i] is located within another folder[j], it is called a sub-folder of it.
The format of a path is one or more concatenated strings of the form: / followed by one or more lowercase English letters. For example, /leetcode and /leetcode/problems are valid paths while an empty string and / are not.

输入一个字符串数组floder,需要输出去掉所有子目录的一个List<String>,输入的字符串都是目录的路径,且以"/"开头

folder = ["/a","/a/b","/c/d","/c/d/e","/c/f"]
/a/b/a的子目录,/c/d/e/c/d的子目录,删去这两个,输出为["/a","/c/d","/c/f"]

最容易想到的是直接使用List放置结果,然后遍历folder,伪代码如下:

for (String s1: folder)
    for (String s2: ret) { // ret是List<String>类型
        if (s1是s2子目录)
            break;
        if (s2是s1子目录) {
            ret中的s2替换为s1
            break;
        }
        ret中添加s1
    }

判断子目录可以是拿出两个子目录对照,也可以把当前目录的父目录拿出来一个一个查,然后再查当前目录是不是其他的父目录

举例:当前目录为/a/b/c,先去找retList<String>类型)中是否有/a,再看是否有/a/b,最后去掉ret中没有以/a/b/c/开头的,然后添加/a/b/c/

前两步是看有没有父目录,后一步是看有没有当前目录的子目录,前两步在ret中挨个查找,效率很低,如果使用Set,那么就很好解决了,每次只要看父目录在Set中是否存在,后一步有两种办法

  1. 遍历Set然后判断是不是以/a/b/c开头的
  2. 按照顺序遍历,"/a/b", "/a"这个顺序,只进行前半部分的判断,是没有办法将它们筛选掉的,但是如果它们顺序为"/a", "/a/b",就可以筛选掉/a/b,所以如果正序倒序都建立一个Set,就可以分别去除掉在后面和前面子目录,然后取出两个Set中的公共部分,就是结果,最终代码如下:
class Solution {
    public List<String> removeSubfolders(String[] folder) {
        List<String> ret = new ArrayList<String>();
        
        Set<String> set1 = new HashSet<String>();
        Set<String> set2 = new HashSet<String>();
        
        // 正序和反序分别生成的set
        for (int i=0; i<folder.length; i++)
            addEle(set1, folder[i]);        
        for (int i=folder.length-1; i>=0; i--)
            addEle(set2, folder[i]);
        
        // 提取出共同的部分,添加到ret中
        for (String s: set1)
            if (set2.contains(s))
                ret.add(s);
        
        return ret;
    }
    
    private void addEle(Set<String> set, String s) {
        int index = 1, nextIndex = 0;
        // 如果set中有s的父目录,那么当前目录就不需要添加到set中了
        while ((nextIndex = s.indexOf('/', index)) != -1) {
            if (set.contains(s.substring(0, nextIndex)))
                return;
            index = nextIndex + 1;
        }
        // set中不存在s的父目录,所以添加s
        set.add(s);
    }
}
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 个人学习批处理的初衷来源于实际工作;在某个迭代版本有个BS(安卓手游模拟器)大需求,从而在测试过程中就重复涉及到...
    Luckykailiu阅读 10,289评论 0 11
  • 官网 中文版本 好的网站 Content-type: text/htmlBASH Section: User ...
    不排版阅读 10,000评论 0 5
  • 如果需要原文档(因文体限制,部分表格无法呈现)请联系QQ1769090563 本文由中医仲景协会整理收集 《内经选...
    陶墨阅读 35,210评论 0 33
  • 常用模块 认识模块 什么是模块 什么是模块? 常见的场景:一个模块就是一个包含了python定义和声明的文件,文...
    go以恒阅读 6,218评论 0 6
  • 在上海迪士尼乐园游玩时,我拍到了一种很特别的花。 这种花,是我第二次拍到,第一次是在上海植物园游玩时拍...
    清兮F阅读 4,166评论 1 6

友情链接更多精彩内容