LeetCode每日一题(1233. Remove Sub-Folders from the Filesystem)

本文介绍了一种去除文件系统中指定目录下所有子目录的方法。通过构建 Trie 树结构来存储并分析路径,实现高效查找及过滤子目录。文章详细解释了 Trie 结构的设计与实现过程,并提供了完整的 Rust 代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Given a list of folders folder, return the folders after removing all sub-folders in those folders. You may return the answer in any order.

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.

Example 1:

Input: folder = [“/a”,“/a/b”,“/c/d”,“/c/d/e”,“/c/f”]
Output: [“/a”,“/c/d”,“/c/f”]

Explanation: Folders “/a/b” is a subfolder of “/a” and “/c/d/e” is inside of folder “/c/d” in our filesystem.

Example 2:

Input: folder = [“/a”,“/a/b/c”,“/a/b/d”]
Output: [“/a”]

Explanation: Folders “/a/b/c” and “/a/b/d” will be removed because they are subfolders of “/a”.

Example 3:

Input: folder = [“/a/b/c”,“/a/b/ca”,“/a/b/d”]
Output: [“/a/b/c”,“/a/b/ca”,“/a/b/d”]

Constraints:

  • 1 <= folder.length <= 4 * 104
  • 2 <= folder[i].length <= 100
  • folder[i] contains only lowercase letters and ‘/’.
  • folder[i] always starts with the character ‘/’.
  • Each folder name is unique.

想了想, 还是得做道题。

这题其实就是找当前路径的所有父路径是不是同样在所给的 folder 中出现过, 我是采用类似与 Trie 的形式进行表达的, 每次添加新的路径都从根上进行添加, 节点的属性中有一个 is_shortest 的属性, 有点类似于字符串 Trie 中用来标识是不是一个单词结尾的属性, 这里表示的是从根节点到当前节点所组成的 path 是不是在 folder 中出现过, 在添加 path 的过程中, 如果遇到 is_shortest=true 的节点, 那就不必再添加下去, 因为下面的所有 path 都是这个节点的 sub folder, 不会出现在答案中。另一方面, 我们在添加过程中, 当我们走到 path 的末尾, 那我们要把当前节点的 is_shortest 设为 true



use std::collections::HashMap;

struct Node {
    is_shortest: bool,
    children: Tree,
}

struct Tree(HashMap<String, Node>);

impl Tree {
    fn new() -> Self {
        Self(HashMap::new())
    }

    fn add(&mut self, mut path: Vec<String>) {
        if path.is_empty() {
            return;
        }
        let section = path.remove(0);
        if let Some(next) = self.0.get_mut(&section) {
            if next.is_shortest {
                return;
            }
            if path.is_empty() {
                next.is_shortest = true;
                return;
            }
            next.children.add(path);
            return;
        }
        let mut node = Node {
            is_shortest: path.is_empty(),
            children: Tree::new(),
        };
        node.children.add(path);
        self.0.insert(section, node);
    }

    fn short_pathes(&self, curr: String, ans: &mut Vec<String>) {
        for (k, v) in &self.0 {
            let mut path = curr.clone();
            path.push('/');
            path.push_str(k);
            if v.is_shortest {
                ans.push(path);
                continue;
            }
            v.children.short_pathes(path, ans);
        }
    }
}

impl Solution {
    pub fn remove_subfolders(folder: Vec<String>) -> Vec<String> {
        let mut tree = Tree::new();
        for path in folder {
            let sections: Vec<String> = path
                .split("/")
                .map(|s| s.to_owned())
                .filter(|v| v != "")
                .collect();
            tree.add(sections);
        }
        let mut ans = Vec::new();
        tree.short_pathes("".into(), &mut ans);
        ans
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值