1233. Remove Sub-Folders from the Filesystem

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.

 

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 * 10^4
  • 2 <= folder[i].length <= 100
  • folder[i] contains only lowercase letters and '/'
  • folder[i] always starts with character '/'
  • Each folder name is unique.

Rust Solution

struct Solution;
use std::collections::HashSet;

impl Solution {
    fn remove_subfolders(folder: Vec<String>) -> Vec<String> {
        let mut hs: HashSet<String> = HashSet::new();
        for s in folder {
            hs.insert(s);
        }
        let mut res = vec![];
        for s in &hs {
            if !Self::is_subfolder(&s, &hs) {
                res.push(s.clone());
            }
        }
        res
    }

    fn is_subfolder(s: &str, hs: &HashSet<String>) -> bool {
        let n = s.len();
        for i in 0..n {
            if &s[i..=i] == "/" {
                if hs.contains(&s[0..i]) {
                    return true;
                }
            }
        }
        false
    }
}

#[test]
fn test() {
    let folder = vec_string!["/a", "/a/b", "/c/d", "/c/d/e", "/c/f"];
    let mut res = vec_string!["/a", "/c/d", "/c/f"];
    let mut ans = Solution::remove_subfolders(folder);
    ans.sort();
    res.sort();
    assert_eq!(ans, res);
    let folder = vec_string!["/a", "/a/b/c", "/a/b/d"];
    let mut res = vec_string!["/a"];
    let mut ans = Solution::remove_subfolders(folder);
    ans.sort();
    res.sort();
    assert_eq!(ans, res);
    let folder = vec_string!["/a/b/c", "/a/b/ca", "/a/b/d"];
    let mut res = vec_string!["/a/b/c", "/a/b/ca", "/a/b/d"];
    let mut ans = Solution::remove_subfolders(folder);
    ans.sort();
    res.sort();
    assert_eq!(ans, res);
}

Having problems with this solution? Click here to submit an issue on github.