588. Design In-Memory File System

Design In-Memory File System - LeetCode

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.

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.
1 <= content.length <= 50
At most 300 calls will be made to ls, mkdir, addContentToFile, and readContentFromFile.

  • code
class Node:
    def __init__(self):
        self.isFile = False
        self.files = defaultdict(Node)
        self.data = ""

class FileSystem:

    def __init__(self):
        self.root = Node()

    def ls(self, path: str) -> List[str]:
        root = self.root
        path_list = path.split("/")
        for p in path_list: # /a/b/c  empty, a, b, c
            if p:
                root = root.files[p]
        if root.isFile: return [p]
        # return list(sorted(root.files.keys()))
        return list(sorted(root.files)) # same as above
        

    def mkdir(self, path: str) -> None:
        root = self.root
        path_list = path.split("/")
        for p in path_list: # /a/b/c  empty, a, b, c
            if p:
                root = root.files[p]

    def addContentToFile(self, filePath: str, content: str) -> None:
        root = self.root
        path_list = filePath.split("/")
        for p in path_list: # /a/b/c  empty, a, b, c
            if p:
                root = root.files[p]
        root.isFile = True
        root.data += content

    def readContentFromFile(self, filePath: str) -> str:
        root = self.root
        path_list = filePath.split("/")
        for p in path_list: # /a/b/c  empty, a, b, c
            if p:
                root = root.files[p]
        return root.data        
        


# 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)
  • code shorter
class Node:
    def __init__(self):
        self.files = defaultdict(Node)
        self.data = ""

class FileSystem:

    def __init__(self):
        self.root = Node()
        
    def find(self, path):
        root = self.root
        path_list = path.split("/")
        for p in path_list:
            if p: root = root.files[p]  # /a/b/c  empty, a, b, c
        return root
        
    def ls(self, path: str) -> List[str]:
        root = self.find(path)
        if root.data: 
            return [path.split("/")[-1]]
        # return list(sorted(root.files.keys()))
        return list(sorted(root.files)) # same as above

    def mkdir(self, path: str) -> None:
        self.find(path)
        
    def addContentToFile(self, filePath: str, content: str) -> None:
        root = self.find(filePath)
        root.data += content

    def readContentFromFile(self, filePath: str) -> str:
        root = self.find(filePath)
        return root.data        
        


# 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)