Skip to main content
Back to problems
#588
Hard Algorithms

Design in memory file system

Hash Table String Design Trie Sorting
48.4% acceptance
Mar 31, 2026
1584
175
Design a data structure that simulates an in-memory file system. Implement the FileSystem class: FileSystem() Initializes the object of the system. List ls(String path) If path is a file path, returns a list that only contains this file's name. If path is a directory path, returns the list of file and directory names in this directory. The answer should in lexicographic order. void mkdir(String path) Makes a new directory according to the given path. The given directory path does not exist. If the middle directories in the path do not exist, you should create them as well. void addContentToFile(String filePath, String content) If filePath does not exist, creates that file containing given content. If filePath already exists, appends the given content to original content. String readContentFromFile(String filePath) Returns the content in the file at filePath.

Solution

Rust
Time O(n log n)
Space O(n)
LeetCode
solution.rs
use std::collections::BTreeMap;

struct FileSystem {
  children: BTreeMap<String, FileSystem>,
  content: String,
  is_file: bool,
}

impl FileSystem {
  fn new() -> Self {
    FileSystem {
      children: BTreeMap::new(),
      content: String::new(),
      is_file: false,
    }
  }

  fn ls(&self, path: String) -> Vec<String> {
    let node = self.traverse(&path);
    if node.is_file {
      let name = path.rsplit('/').next().unwrap().to_string();
      return vec![name];
    }
    node.children.keys().cloned().collect()
  }

  fn mkdir(&mut self, path: String) {
    self.ensure_path(&path);
  }

  fn add_content_to_file(&mut self, file_path: String, content: String) {
    let node = self.ensure_path(&file_path);
    node.is_file = true;
    node.content.push_str(&content);
  }

  fn read_content_from_file(&self, file_path: String) -> String {
    self.traverse(&file_path).content.clone()
  }

  fn traverse(&self, path: &str) -> &FileSystem {
    let parts: Vec<&str> = path.split('/').filter(|s| !s.is_empty()).collect();
    let mut node = self;
    for p in parts {
      node = node.children.get(p).unwrap();
    }
    node
  }

  fn ensure_path(&mut self, path: &str) -> &mut FileSystem {
    let parts: Vec<&str> = path.split('/').filter(|s| !s.is_empty()).collect();
    let mut node = self;
    for p in parts {
      node = node.children.entry(p.to_string()).or_insert_with(FileSystem::new);
    }
    node
  }
}