美文网首页IT@程序员猿媛
LeetCode: 1233. Remove Sub-Folde

LeetCode: 1233. Remove Sub-Folde

作者: ringawho | 来源:发表于2020-04-04 11:55 被阅读0次

    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);
        }
    }
    

    相关文章

      网友评论

        本文标题:LeetCode: 1233. Remove Sub-Folde

        本文链接:https://www.haomeiwen.com/subject/rpvdphtx.html