Design In-Memory File System

Trie of directories where leaf nodes carry a content string — recursive path walk for ls/mkdir/read/write.

Hard
Time O(L) per op Space O(total paths)
LeetCode
6 min read
design trie hash-map string

Problem#

Design a file system with ls, mkdir, addContentToFile, readContentFromFile. Paths are absolute ("/a/b/c"). ls on a file returns a single-element list with the file name; on a directory, the sorted children.

Examples#

  • mkdir("/a/b/c"); ls("/")["a"].
  • addContentToFile("/a/b/c/d", "hello"); readContentFromFile("/a/b/c/d")"hello".

Constraints#

  • Up to 300 calls.

Approach#

Trie node: children map (name → node), file content string. Walk the path component-by-component creating directories as needed. ls on a file returns just its name; on a dir, sorted children.

Solution#

In-Memory File System
class FileSystem {
struct Node {
map<string, Node*> children;
string content;
bool isFile = false;
};
Node* root = new Node();
vector<string> split(const string& path) {
vector<string> parts;
string cur;
for (char c : path) {
if (c == '/') { if (!cur.empty()) { parts.push_back(cur); cur.clear(); } }
else cur.push_back(c);
}
if (!cur.empty()) parts.push_back(cur);
return parts;
}
Node* walk(const vector<string>& parts, bool create) {
Node* cur = root;
for (auto& p : parts) {
if (!cur->children.count(p)) {
if (!create) return nullptr;
cur->children[p] = new Node();
}
cur = cur->children[p];
}
return cur;
}
public:
vector<string> ls(string path) {
auto parts = split(path);
Node* n = walk(parts, false);
if (!n) return {};
if (n->isFile) return { parts.back() };
vector<string> out;
for (auto& [k, _] : n->children) out.push_back(k);
return out;
}
void mkdir(string path) { walk(split(path), true); }
void addContentToFile(string filePath, string content) {
auto parts = split(filePath);
Node* n = walk(parts, true);
n->isFile = true;
n->content += content;
}
string readContentFromFile(string filePath) {
Node* n = walk(split(filePath), false);
return n ? n->content : "";
}
};

Editorial#

Using std::map keeps children sorted automatically, eliminating an explicit sort in ls. Treating files as trie leaves with the isFile flag avoids a separate file-vs-dir representation. addContentToFile is idempotent on directory creation — walks the path with create = true and appends content.

Complexity#

  • Time: O(L) per op (L = path length); ls on a directory is O(L + k log k) for k children.
  • Space: proportional to total paths.

Concept revision#

Search ESC

Keyboard shortcuts

Shortcuts are disabled while typing in inputs.