Design In-Memory File System
Problem
Implement ls(path), mkdir(path), addContentToFile(path, content), readContentFromFile(path).
ops: mkdir('/a/b/c'); addContentToFile('/a/b/c/d','hello')['a'] then ['hello']class FileSystem:
def __init__(self):
self.tree = {}
def _walk(self, p):
cur = self.tree
for part in [x for x in p.split('/') if x]: cur = cur.setdefault(part, {})
return cur
def ls(self, p):
cur = self._walk(p)
if isinstance(cur, str): return [p.split('/')[-1]]
return sorted(cur)
def mkdir(self, p): self._walk(p)
def addContentToFile(self, p, c):
parent = self._walk('/'.join(p.split('/')[:-1]))
parent[p.split('/')[-1]] = parent.get(p.split('/')[-1], '') + c
def readContentFromFile(self, p):
return self._walk('/'.join(p.split('/')[:-1]))[p.split('/')[-1]]
class FileSystem {
constructor() { this.root = {}; }
walk(p) { let cur = this.root; for (const part of p.split('/').filter(Boolean)) cur = cur[part] ||= {}; return cur; }
ls(p) { const cur = this.walk(p); return typeof cur === 'string' ? [p.split('/').pop()] : Object.keys(cur).sort(); }
mkdir(p) { this.walk(p); }
addContentToFile(p, c) { const parts = p.split('/'); const f = parts.pop(); const parent = this.walk(parts.join('/')); parent[f] = (parent[f] || '') + c; }
readContentFromFile(p) { const parts = p.split('/'); const f = parts.pop(); return this.walk(parts.join('/'))[f]; }
}
class FileSystem {
Map root = new TreeMap<>();
Map walk(String p) {
Map cur = root;
for (String part : p.split("/")) if (!part.isEmpty()) cur = (Map) cur.computeIfAbsent(part, k -> new TreeMap<>());
return cur;
}
public List ls(String p) { return new ArrayList<>(walk(p).keySet()); }
public void mkdir(String p) { walk(p); }
public void addContentToFile(String p, String c) {
String[] parts = p.split("/"); String f = parts[parts.length-1];
Map parent = walk(p.substring(0, p.lastIndexOf('/')));
parent.merge(f, c, (a, b) -> (String) a + b);
}
public String readContentFromFile(String p) {
String f = p.substring(p.lastIndexOf('/')+1);
return (String) walk(p.substring(0, p.lastIndexOf('/'))).get(f);
}
}
class FileSystem {
struct Node { map ch; string content; bool isFile = false; } *root = new Node;
Node* walk(string p) { Node* c = root; stringstream ss(p); string t;
while (getline(ss, t, '/')) if (!t.empty()) { if (!c->ch.count(t)) c->ch[t] = new Node; c = c->ch[t]; }
return c;
}
public:
vector ls(string p) { Node* c = walk(p); if (c->isFile) return {p.substr(p.find_last_of('/')+1)};
vector o; for (auto& [k, _] : c->ch) o.push_back(k); return o; }
void mkdir(string p) { walk(p); }
void addContentToFile(string p, string c) { Node* n = walk(p); n->isFile = true; n->content += c; }
string readContentFromFile(string p) { return walk(p)->content; }
};
Explanation
A file system is really just a tree: folders contain folders which contain files. We model that tree with nested dictionaries, where each key is a name and its value is either another dictionary (a directory) or a string (a file's content).
The shared helper is _walk(path). It splits the path on /, then steps into each part one at a time, creating the entry if it does not exist (setdefault(part, {})). It returns whatever node the path points to.
mkdir is just _walk(path) — walking the path creates every missing directory along the way. ls walks to the node and, if it is a directory, returns its sorted keys; if it is a file, it returns just that file's name.
addContentToFile walks to the parent directory (everything before the last name), then sets or appends the content under the final name. readContentFromFile walks to the parent and returns the stored string.
Example: mkdir('/a/b/c') builds nested folders a → b → c. Then addContentToFile('/a/b/c/d','hello') walks to c and stores 'hello' under d. Now ls('/') returns ['a'] and reading /a/b/c/d gives 'hello'.