Skip to content

1166. Design File System 👍

  • Time: Constructor: $O(1)$, createPath(path: str, value: int): $O(|\texttt{path}|)$, get(path: str): $O(|\texttt{path}|)$
  • Space: $O(|\texttt{createPath(path: str, value: int)}|)$
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
struct TrieNode {
  unordered_map<string, shared_ptr<TrieNode>> children;
  int value;
  TrieNode(int value) : value(value) {}
};

class FileSystem {
 public:
  bool createPath(string path, int value) {
    const vector<string> subpaths = getSubpaths(path);
    shared_ptr<TrieNode> node = root;

    for (int i = 0; i < subpaths.size() - 1; ++i) {
      auto it = node->children.find(subpaths[i]);
      if (it == end(node->children))
        return false;
      node = it->second;
    }

    if (node->children.count(subpaths.back()))
      return false;
    node->children[subpaths.back()] = make_shared<TrieNode>(value);
    return true;
  }

  int get(string path) {
    const vector<string> subpaths = getSubpaths(path);
    shared_ptr<TrieNode> node = root;

    for (const string& subpath : getSubpaths(path)) {
      auto it = node->children.find(subpath);
      if (it == end(node->children))
        return -1;
      node = it->second;
    }

    return node->value;
  }

 private:
  shared_ptr<TrieNode> root = make_shared<TrieNode>(0);

  vector<string> getSubpaths(const string& path) {
    vector<string> subpaths;
    istringstream iss(path);
    for (string subpath; getline(iss, subpath, '/');)
      if (!subpath.empty())
        subpaths.push_back(subpath);
    return subpaths;
  }
};
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
class TrieNode {
  public Map<String, TrieNode> children = new HashMap<>();
  public int value;
  public TrieNode(int value) {
    this.value = value;
  }
}

class FileSystem {
  public boolean createPath(String path, int value) {
    final String[] subpaths = path.split("/");
    TrieNode node = root;

    for (int i = 1; i < subpaths.length - 1; ++i) {
      if (!node.children.containsKey(subpaths[i]))
        return false;
      node = node.children.get(subpaths[i]);
    }

    final String lastSubpath = subpaths[subpaths.length - 1];
    if (node.children.containsKey(lastSubpath))
      return false;
    node.children.put(lastSubpath, new TrieNode(value));
    return true;
  }

  public int get(String path) {
    final String[] subpaths = path.split("/");
    TrieNode node = root;

    for (int i = 1; i < subpaths.length; ++i) {
      if (!node.children.containsKey(subpaths[i]))
        return -1;
      node = node.children.get(subpaths[i]);
    }

    return node.value;
  }

  private TrieNode root = new TrieNode(0);
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
class TrieNode:
  def __init__(self, value: int = 0):
    self.children: Dict[str, TrieNode] = collections.defaultdict(TrieNode)
    self.value = value

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

  def createPath(self, path: str, value: int) -> bool:
    node: TrieNode = self.root
    subpaths = path.split('/')

    for i in range(1, len(subpaths) - 1):
      if subpaths[i] not in node.children:
        return False
      node = node.children[subpaths[i]]

    if subpaths[-1] in node.children:
      return False
    node.children[subpaths[-1]] = TrieNode(value)
    return True


  def get(self, path: str) -> int:
    node: TrieNode = self.root

    for subpath in path.split('/')[1:]:
      if subpath not in node.children:
        return -1
      node = node.children[subpath]

    return node.value