Talentd
FleetCode
Make and follow sheets.Sign in

Design In-Memory File System solution and explanation

HardDesignHash TableSortingString5 min read48.0% acceptanceUpdated 23 Mar 2026Premium elsewhere, free here
DESIGN IN-MEMORY FILE SYSTEM | LEETCODE # 588 | PYTHON SOLUTIONCracking FAANG · 21:37 · 17K viewsWatch on YouTube
7 more videos on this problem
  1. DESIGN IN-MEMORY FILE SYSTEM | LEETCODE # 588 | PYTHON SOLUTIONCracking FAANG · 21:37 · 17K views
  2. Google Coding Interview Question | Leetcode 588 | Design In-Memory File SystemWorkWithGoogler · 29:11 · 12K views
  3. [Java] Leetcode 588. Design In-Memory File System [Trie #2]Eric Programming · 16:19 · 11K views
  4. 588. Design In-Memory File System (Leetcode Hard)Programming Live with Larry · 16:54 · 1K views
  5. Leetcode 588. Design In-memory file systemSunny Gupta · 57:41 · 499 views
  6. Design In-Memory File System - LeetCode System Design Interview ProblemCodeLucky · 4:16 · 191 views
  7. Leetcode #588: Design in memory file system JS solutionJack Chen · 4:26 · 174 views
  8. 【Edward Shi】LeetCode 588. Design In-Memory File System 设计内存文件系统 |算法面试|刷题找工作|北美CS求职|力扣Edward Shi · 20:35 · 67 views

The problem

Design a data structure that simulates an in-memory file system.

Implement the FileSystem class:

  • FileSystem() Initializes the object of the system.
  • List<String> 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.

Example 1:

Input
["FileSystem", "ls", "mkdir", "addContentToFile", "ls", "readContentFromFile"]
[[], ["/"], ["/a/b/c"], ["/a/b/c/d", "hello"], ["/"], ["/a/b/c/d"]]
Output
[null, [], null, null, ["a"], "hello"]

Explanation
FileSystem fileSystem = new FileSystem();
fileSystem.ls("/"); // return []
fileSystem.mkdir("/a/b/c");
fileSystem.addContentToFile("/a/b/c/d", "hello");
fileSystem.ls("/"); // return ["a"]
fileSystem.readContentFromFile("/a/b/c/d"); // return "hello"

Constraints:

  • 1 <= path.length, filePath.length <= 100
  • path and filePath are absolute paths which begin with '/' and do not end with '/' except that the path is just "/".
  • You can assume that all directory names and file names only contain lowercase letters, and the same names will not exist in the same directory.
  • You can assume that all operations will be passed valid parameters, and users will not attempt to retrieve file content or list a directory or file that does not exist.
  • You can assume that the parent directory for the file in addContentToFile will exist.
  • 1 <= content.length <= 50
  • At most 300 calls will be made to ls, mkdir, addContentToFile, and readContentFromFile.

Approach overview

Problem Overview: Design a file system that runs entirely in memory. You must support directory listing (ls), creating directories (mkdir), adding content to files (addContentToFile), and reading file content (readContentFromFile) while maintaining lexicographically sorted directory listings.

Approach 1: HashMap-Based Directory Tree (Trie Structure) (Time: O(p + k log k), Space: O(n))

Treat the file system as a tree where each directory is a node and edges represent path segments. Split the path by / and traverse the tree one segment at a time. Each node stores a hash map of children (name → node), a flag indicating whether it is a file, and a string builder for file content. Directory operations like mkdir simply create missing nodes during traversal. For ls, return the file name if the path is a file, otherwise collect child keys and sort them lexicographically. Traversal takes O(p) where p is the number of path components, and sorting the directory listing costs O(k log k) where k is the number of entries.

This approach behaves like a simplified Trie where each level represents a folder name instead of a character. Using a hash table for children ensures constant-time lookup during traversal. File content appends are efficient because you only modify the node representing the file.

Approach 2: Trie with File Metadata and Lazy Sorting (Time: O(p) average, O(k log k) for listing, Space: O(n))

Another implementation models directories and files explicitly with a Trie node class containing metadata such as isFile, content, and a children map. Path traversal works the same way: split the path, iterate through segments, and create nodes when necessary. Instead of sorting every time ls is called, some implementations maintain directory entries in sorted containers or cache sorted results when modifications occur. This reduces repeated sorting overhead when directories are listed frequently.

The Trie structure naturally represents hierarchical file paths, making operations predictable and easy to reason about. String parsing of paths relies on standard string operations, and node traversal handles all file system operations consistently.

Recommended for interviews: The HashMap-backed Trie is the expected solution. It directly models the hierarchical file system and keeps each operation near O(p). Interviewers mainly check whether you design a clean node structure, correctly parse paths, and handle the lexicographic ordering requirement for ls. A simpler map-only idea can show understanding, but the Trie-style directory tree demonstrates solid system design thinking.

Solution

class Trie:
    def __init__(self):
        self.name = None
        self.isFile = False
        self.content = []
        self.children = {}

    def insert(self, path, isFile):
        node = self
        ps = path.split('/')
        for p in ps[1:]:
            if p not in node.children:
                node.children[p] = Trie()
            node = node.children[p]
        node.isFile = isFile
        if isFile:
            node.name = ps[-1]
        return node

    def search(self, path):
        node = self
        if path == '/':
            return node
        ps = path.split('/')
        for p in ps[1:]:
            if p not in node.children:
                return None
            node = node.children[p]
        return node


class FileSystem:
    def __init__(self):
        self.root = Trie()

    def ls(self, path: str) -> List[str]:
        node = self.root.search(path)
        if node is None:
            return []
        if node.isFile:
            return [node.name]
        return sorted(node.children.keys())

    def mkdir(self, path: str) -> None:
        self.root.insert(path, False)

    def addContentToFile(self, filePath: str, content: str) -> None:
        node = self.root.insert(filePath, True)
        node.content.append(content)

    def readContentFromFile(self, filePath: str) -> str:
        node = self.root.search(filePath)
        return ''.join(node.content)


# Your FileSystem object will be instantiated and called as such:
# obj = FileSystem()
# param_1 = obj.ls(path)
# obj.mkdir(path)
# obj.addContentToFile(filePath,content)
# param_4 = obj.readContentFromFile(filePath)
class Trie {
    String name;
    boolean isFile;
    StringBuilder content = new StringBuilder();
    Map<String, Trie> children = new HashMap<>();

    Trie insert(String path, boolean isFile) {
        Trie node = this;
        String[] ps = path.split("/");
        for (int i = 1; i < ps.length; ++i) {
            String p = ps[i];
            if (!node.children.containsKey(p)) {
                node.children.put(p, new Trie());
            }
            node = node.children.get(p);
        }
        node.isFile = isFile;
        if (isFile) {
            node.name = ps[ps.length - 1];
        }
        return node;
    }

    Trie search(String path) {
        Trie node = this;
        String[] ps = path.split("/");
        for (int i = 1; i < ps.length; ++i) {
            String p = ps[i];
            if (!node.children.containsKey(p)) {
                return null;
            }
            node = node.children.get(p);
        }
        return node;
    }
}

class FileSystem {
    private Trie root = new Trie();

    public FileSystem() {
    }

    public List<String> ls(String path) {
        List<String> ans = new ArrayList<>();
        Trie node = root.search(path);
        if (node == null) {
            return ans;
        }
        if (node.isFile) {
            ans.add(node.name);
            return ans;
        }
        for (String v : node.children.keySet()) {
            ans.add(v);
        }
        Collections.sort(ans);
        return ans;
    }

    public void mkdir(String path) {
        root.insert(path, false);
    }

    public void addContentToFile(String filePath, String content) {
        Trie node = root.insert(filePath, true);
        node.content.append(content);
    }

    public String readContentFromFile(String filePath) {
        Trie node = root.search(filePath);
        return node.content.toString();
    }
}

/**
 * Your FileSystem object will be instantiated and called as such:
 * FileSystem obj = new FileSystem();
 * List<String> param_1 = obj.ls(path);
 * obj.mkdir(path);
 * obj.addContentToFile(filePath,content);
 * String param_4 = obj.readContentFromFile(filePath);
 */
type Trie struct {
	name     string
	isFile   bool
	content  strings.Builder
	children map[string]*Trie
}

func newTrie() *Trie {
	m := map[string]*Trie{}
	return &Trie{children: m}
}

func (this *Trie) insert(path string, isFile bool) *Trie {
	node := this
	ps := strings.Split(path, "/")
	for _, p := range ps[1:] {
		if _, ok := node.children[p]; !ok {
			node.children[p] = newTrie()
		}
		node, _ = node.children[p]
	}
	node.isFile = isFile
	if isFile {
		node.name = ps[len(ps)-1]
	}
	return node
}

func (this *Trie) search(path string) *Trie {
	if path == "/" {
		return this
	}
	node := this
	ps := strings.Split(path, "/")
	for _, p := range ps[1:] {
		if _, ok := node.children[p]; !ok {
			return nil
		}
		node, _ = node.children[p]
	}
	return node
}

type FileSystem struct {
	root *Trie
}

func Constructor() FileSystem {
	root := newTrie()
	return FileSystem{root}
}

func (this *FileSystem) Ls(path string) []string {
	var ans []string
	node := this.root.search(path)
	if node == nil {
		return ans
	}
	if node.isFile {
		ans = append(ans, node.name)
		return ans
	}
	for v := range node.children {
		ans = append(ans, v)
	}
	sort.Strings(ans)
	return ans
}

func (this *FileSystem) Mkdir(path string) {
	this.root.insert(path, false)
}

func (this *FileSystem) AddContentToFile(filePath string, content string) {
	node := this.root.insert(filePath, true)
	node.content.WriteString(content)
}

func (this *FileSystem) ReadContentFromFile(filePath string) string {
	node := this.root.search(filePath)
	return node.content.String()
}

/**
 * Your FileSystem object will be instantiated and called as such:
 * obj := Constructor();
 * param_1 := obj.Ls(path);
 * obj.Mkdir(path);
 * obj.AddContentToFile(filePath,content);
 * param_4 := obj.ReadContentFromFile(filePath);
 */
Try this approach in the editor

Complexity analysis

ApproachTimeSpaceWhen to Use
HashMap Directory Tree (Trie)O(p + k log k)O(n)General case; simple design with fast path traversal and flexible directory growth
Trie with Cached/Ordered ChildrenO(p) average, O(k log k) for listingO(n)When directories are listed frequently and sorting repeatedly becomes expensive

Frequently asked questions

Is Design In-Memory File System easy or hard?

Design In-Memory File System is considered a Hard problem because it combines data structure design, path parsing, and multiple operations that must interact correctly. Implementing the Trie-like structure and handling edge cases for files versus directories requires careful coding.

Design In-Memory File System Python/Java solution

Both Python and Java implementations follow the same idea: define a node class with a children map, a file flag, and file content storage. Split the input path by '/', traverse or create nodes, append content for files, and sort child names when returning directory listings.

How to solve Design In-Memory File System in O(n)?

Store the file system as a tree (Trie) where each node represents a directory or file. Traverse the path segments to reach the target node and create missing nodes during mkdir or file creation. Each operation processes path components once, making traversal O(p) while storing nodes takes O(n) total space.

What is the best approach for Design In-Memory File System?

The most common solution uses a Trie-like directory tree where each node stores a hash map of child names to nodes. Paths are split by '/' and traversed sequentially. This structure supports mkdir, file creation, and content appending efficiently while allowing lexicographic sorting of directory entries during ls operations.

Is Design In-Memory File System asked at Google/Amazon/Meta?

Design-style data structure problems like this frequently appear in interviews at companies such as Google, Amazon, and Meta. The question tests object-oriented design, Trie structures, and handling hierarchical data with efficient lookups.

What data structure is used in Design In-Memory File System?

A Trie-style tree combined with hash maps is typically used. Each node represents a directory or file and stores a map from name to child node, along with file metadata such as content and a file flag. This structure mirrors how hierarchical file paths work.

What is the time complexity of Design In-Memory File System?

Most operations run in O(p) time where p is the number of path segments. The ls operation may require sorting directory entries, which adds O(k log k) where k is the number of files or subdirectories in that directory. Space complexity is O(n) for storing all files and directories.

Comments

Now write it yourselfClose this page and solve Design In-Memory File System in the editor, without looking.
Practise Design In-Memory File System