LeetCode破解之重复文件

160 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第29天,点击查看活动详情

题目描述

给你一个目录信息列表 paths ,包括目录路径,以及该目录中的所有文件及其内容,请你按路径返回文件系统中的所有重复文件。答案可按 任意顺序 返回。

一组重复的文件至少包括 两个 具有完全相同内容的文件。

输入 列表中的单个目录信息字符串的格式如下:

  • "root/d1/d2/.../dm f1.txt(f1_content) f2.txt(f2_content) ... fn.txt(fn_content)"

这意味着,在目录 root/d1/d2/.../dm 下,有 n 个文件 ( f1.txt, f2.txt ... fn.txt ) 的内容分别是 ( f1_content, f2_content ... fn_content ) 。注意:n >= 1 且 m >= 0 。如果 m = 0 ,则表示该目录是根目录。

输出 是由 重复文件路径组 构成的列表。其中每个组由所有具有相同内容文件的文件路径组成。文件路径是具有下列格式的字符串:

  • "directory_path/file_name.txt"

示例 1:

输入:paths = ["root/a 1.txt(abcd) 2.txt(efgh)","root/c 3.txt(abcd)","root/c/d 4.txt(efgh)","root 4.txt(efgh)"]

输出:[["root/a/2.txt","root/c/d/4.txt","root/4.txt"],["root/a/1.txt","root/c/3.txt"]]

哈希表法HashMap

这个题目我的初步思路是:使用哈希表做映射,快速定位重复文件,理解起来很容易。首先我们知道题目给的String的格式 [路径, path1, path2...]。并且不重复的文件,不需要输出。只输出重复的文件的路径。(根据map的list的大小判断,只输出大于2的)。用map存储内容相同的文件的路径。步骤如下:

  • 定义初始化的哈希表,并分隔开path方便遍历。
  • 遍历所有的路径,内层遍历所有文件。
  • 分别获取文件后括号当中的字符串、文件括号中的分组、获取文件名。如果map当中有该分组的列表,就加入,没有就新建该分组对应的列表。
  • 最后遍历完所有分组,如果该分组文件数量小于2,就代表没有重复文件,就不需要加入结果数组,否则加入结果数组。
class Solution {
    public List<List<String>> findDuplicate(String[] paths) {
        Map<String, List<String>> map = new HashMap<>(16);
        for (String path : paths) {
            String[] split = path.split(" ");
            String dir = split[0];
            for (int i = 1; i < split.length; i++) {
                String file = split[i];
                String filename = file.substring(0, file.indexOf('('));
                String content = file.substring(file.indexOf('('), file.length() - 1);
                List<String> list = map.computeIfAbsent(content, k -> new ArrayList<>());
                list.add(dir + "/" + filename);
            }
        }
        List<List<String>> lists = new ArrayList<>(map.size());
        for (List<String> list : map.values()) {
            if (list.size() > 1) {
                lists.add(list);
            }
        }
        return lists;
    }
}

最后

关于后续的话,如果文件很多,我觉得要用 树的形式, 然后存 文件的MD5或者其他的特征校验码,SHA128之类的.不需要全部去逐位比较文件内容。