### 题目描述:
员工A的磁盘空间经常被耗尽,他需要找到占用空间最大的目录或文件,然后决定如何清理文件释放空间。给定某一目录,请编写程序帮助他统计该目录内一级子目录和文件的占用空间,并返回目标目录一级子项(文件或子目录)中占用空间最大的项。
### 规则说明
1. 目录占用空间为其内部所有文件Size的总和,且目录本身Size为0。
2. 目录深度不高于7层,目录或文件名总长度不超过128字节。
3. 当存在多个子项占用空间均为最大时,多个子项采用字符升序排列。
4. 目标目录不在文件系统中时(输入路径前缀匹配不到任何路径),返回空列表。
### 输入描述
输入:
参数1: 要进行统计的目标目录。
参数2: 文件系统内的文件列表。
参数3: 文件Size列表,该列表中的数据和文件列表存在一一对应关系。
## 输出描述
输出: 目标目录一级子项(文件或子目录)中占用空间最大的项组成的列表。
### 示例1
输入:
/dir1/dir2-1
/dir0/dir1-1/file1-1 /dir1/dir1-1/file1-1 /dir1/dir2-1/file3-1 /dir1/dir2-1/file3-2 /dir1/dir2-1/file3-3
8192 8192 2048 8192 1024
输出:
file3-2
解题思路
本题需要统计指定目录下一级子项(直接子文件或子目录)的占用空间,并返回占用空间最大的一个或多个子项(名称升序)。
目录的占用空间等于其内部所有文件大小之和(递归)。
输入给出目标目录路径、所有文件路径列表(空格分隔)、对应文件大小列表(空格分隔)。
思路一:基于路径前缀匹配 + 字典累加
将文件路径和大小存入字典(路径 → 大小)。
遍历所有文件路径,筛选出以目标目录路径为前缀的文件(注意避免前缀误匹配,如 /dir1 匹配 /dir11,需要确保目标目录后跟 / 或完全相同)。
对于每个符合条件的文件,提取相对于目标目录的剩余路径,取第一级子项名称(即剩余路径中第一个 / 之前的部分,若无 / 则为文件名本身)。
累加该文件大小到对应的一级子项。
若没有任何文件匹配,返回空列表。
找出最大总大小,收集所有达到该大小的子项,按名称升序排序,输出。
思路二:构建树形结构(字典嵌套)
将每个文件路径按 / 分割成目录/文件名列表,构建一棵多叉树,每个节点包含子节点字典和累计大小。
插入文件时,沿着路径向下创建节点,并在叶子节点(文件)上记录大小,同时向上更新父节点累计大小。
最终,目标目录对应的节点就是我们要查询的根。其直接子节点(keys)就是一级子项,每个子节点的累计大小即为该子项的占用空间。
找出累计大小最大的子项(可能有多个),按名称排序输出。
代码实现
思路一:路径前缀匹配 + 字典累加
import sysdef solve_prefix(): lines = sys.stdin.read().strip().splitlines() if not lines: return target = lines[0].strip() # 第二行:文件列表,可能为空 if len(lines) > 1: file_paths = lines[1].strip().split() else: file_paths = [] # 第三行:大小列表 if len(lines) > 2: sizes = list(map(int, lines[2].strip().split())) else: sizes = [] # 构建路径->大小映射 size_map = {} for p, s in zip(file_paths, sizes): size_map[p] = s # 确保目标目录路径末尾不带斜杠 target = target.rstrip('/') # 存储一级子项的总大小 sub_size = {} for path, fsize in size_map.items(): # 检查是否在目标目录下(包括目录本身?但目录本身不是文件,所以必须深度大于) # 如果目标目录是根目录?处理前缀匹配:要么路径等于目标目录(作为文件?但目标目录是目录,不会直接是文件), # 要么路径以 target + '/' 开头 if path == target: # 目标目录本身作为文件?实际上目标目录是目录,不可能有同名文件,忽略 continue if path.startswith(target + '/'): # 提取相对路径 rel = path[len(target)+1:] # 去掉target和后面的/ # 取第一级子项名(第一个/之前的部分) if '/' in rel: sub_name = rel.split('/', 1)[0] else: sub_name = rel sub_size[sub_name] = sub_size.get(sub_name, 0) + fsize if not sub_size: print("") return max_size = max(sub_size.values()) result = [name for name, size in sub_size.items() if size == max_size] result.sort() print(' '.join(result))if __name__ == "__main__": solve_prefix()
思路二:构建树形结构(字典嵌套)
import sysclass TreeNode: def __init__(self, name): self.name = name self.children = {} # name -> TreeNode self.total_size = 0 # 子树总大小(包括所有后代文件)def solve_tree(): lines = sys.stdin.read().strip().splitlines() if not lines: return target = lines[0].strip() if len(lines) > 1: file_paths = lines[1].strip().split() else: file_paths = [] if len(lines) > 2: sizes = list(map(int, lines[2].strip().split())) else: sizes = [] # 构建根节点(虚拟根) root = TreeNode("") # 插入每个文件 for path, fsize in zip(file_paths, sizes): parts = path.split('/') # 跳过空的部分(如第一个/导致空字符串) parts = [p for p in parts if p] cur = root for i, part in enumerate(parts): if part not in cur.children: cur.children[part] = TreeNode(part) cur = cur.children[part] # 文件节点累加大小(叶子节点) cur.total_size += fsize # 向上更新祖先节点总大小 # 这里我们在插入后统一计算,也可以在插入时递归更新,但为避免重复,可以直接在最后递归计算 # 简便方法:插入时向上更新 # 但为了简单,我们之后对整棵树后序遍历计算 # 后序遍历计算每个节点的总大小(包括所有后代文件) def postorder(node): total = node.total_size # 如果是文件节点,已有自己的大小;目录节点初始为0 for child in node.children.values(): total += postorder(child) node.total_size = total return total postorder(root) # 找到目标目录对应的节点 target_parts = [p for p in target.split('/') if p] cur = root for part in target_parts: if part in cur.children: cur = cur.children[part] else: # 目标目录不存在 print("") return # cur 为目标目录节点,其直接子节点即一级子项 if not cur.children: print("") return max_size = max(child.total_size for child in cur.children.values()) result = [name for name, child in cur.children.items() if child.total_size == max_size] result.sort() print(' '.join(result))if __name__ == "__main__": solve_tree()