zoukankan      html  css  js  c++  java
  • 删除子文件夹

    删除子文件夹

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

    我们这样定义「子文件夹」:

    如果文件夹 folder[i] 位于另一个文件夹 folder[j] 下,那么 folder[i] 就是 folder[j] 的子文件夹。
    文件夹的「路径」是由一个或多个按以下格式串联形成的字符串:

    / 后跟一个或者多个小写英文字母。
    例如,/leetcode 和 /leetcode/problems 都是有效的路径,而空字符串和 / 不是。

    示例 1:

    输入:folder = ["/a","/a/b","/c/d","/c/d/e","/c/f"]
    输出:["/a","/c/d","/c/f"]
    解释:"/a/b/" 是 "/a" 的子文件夹,而 "/c/d/e" 是 "/c/d" 的子文件夹。
    示例 2:

    输入:folder = ["/a","/a/b/c","/a/b/d"]
    输出:["/a"]
    解释:文件夹 "/a/b/c" 和 "/a/b/d/" 都会被删除,因为它们都是 "/a" 的子文件夹。
    示例 3:

    输入:folder = ["/a/b/c","/a/b/d","/a/b/ca"]
    输出:["/a/b/c","/a/b/ca","/a/b/d"]

    解法一(暴力求解)

    遍历整个数组, 把每个字符串与数组中的其他字符串做比较,如果有字符串是以"被比较字符串" + "/" 开头, 则认为是子文件夹.

    该方法很容易想到,但缺陷也很明显,时间复杂度是O(n^2)

    代码直接略

    解法二(滑动窗口)

    在解法一中,我们要把每个字符串都与别的字符串做比较,需要消耗非常大的时间,有没有办法可以少比较呢?

    那么,如果这个数组是有序的:首先拿第0个去和第1,2,3......个比较,当第0个与第n个比较,第n个之前都是以 "被比较字符串" + "/"开头,则都可以去掉;

    而第n个不是以 "被比较字符串" + "/"开头,则接下来用第n个继续去和后面的作比较,直到比较结束。

    /**
     * 滑动窗口解法
     * @param folders
     * @return
     */
    public static List<String> removeSubfolders(String[] folders) {
        Arrays.sort(folders);
        List<String> result = new ArrayList<>();
        result.add(folders[0]);
        int left = 0;
        int right = 1;
        for(right = 1;right < folders.length;right++){
            if(!folders[right].contains(folders[left] + "/")){
                result.add(folders[right]);
                left = right;
            }
        }
        return result;
    }
    

    解法三(TreeSet)

    解法三是利用数据结构去解答问题,实际是和第1种有些类似。

    第一步:仍然是先将数组进行排序

    第二步:构造TreeSet, 如果加入的value是以TreeSet "某个结点"+"/" 开头,则忽略掉,否则按顺序加入;

    第三步:将排序后的数组逐个加入到TreeSet中,因为TreeSet是红黑树,所以每次加入的结点都会选择特定的分支比较加入

    /**
     * treeSet解法
     * @param folders
     * @return
     */
    public static List<String> removeSubfolders_treeSet(String[] folders) {
        TreeSet<String> set = new TreeSet<>((str1,str2)->{
            if(str1.contains(str2+"/")){
                return 0;
            }else{
                return str1.compareTo(str2);
            }
        });
        Arrays.sort(folders);
        for(String s: folders){
            set.add(s);
        }
        return new ArrayList<>(set);
    }
    

    总结

    TreeSet的使用

    数组的排序

    算法中:如果碰到的题目是像该题的比较,需要拿每个值去和其他很多值比较,则很可能会需要排序再比较;

    如果像 sum=a+b这样的题目,则大都会用到map

  • 相关阅读:
    VS2010 自动跳过代码现象
    Reverse Linked List II 【纠结逆序!!!】
    Intersection of Two Linked Lists
    Linked List Cycle II
    Remove Nth Node From End of List 【另一个技巧,指针的指针】
    Swap Nodes in Pairs
    Merge Two Sorted Lists
    Remove Duplicates from Sorted List
    Linked List Cycle
    Dungeon Game
  • 原文地址:https://www.cnblogs.com/lfdingye/p/14746883.html
Copyright © 2011-2022 走看看