你需要设计一个文件系统,你可以创建新的路径并将它们与不同的值关联。
路径的格式是一个或多个连接在一起的字符串,形式为: /
,后面跟着一个或多个小写英文字母。例如, " /leetcode"
和 "/leetcode/problems"
是有效路径,而空字符串 ""
和 "/"
不是。
实现 FileSystem
类:
bool createPath(string path, int value)
创建一个新的path
,并在可能的情况下关联一个value
,然后返回true
。如果路径已经存在或其父路径不存在,则返回false
。-
int get(string path)
返回与path
关联的值,如果路径不存在则返回-1
。
示例 1:
输入: ["FileSystem","create","get"] [[],["/a",1],["/a"]] 输出: [null,true,1] 解释: FileSystem fileSystem = new FileSystem(); fileSystem.create("/a", 1); // 返回 true fileSystem.get("/a"); // 返回 1
示例 2:
输入: ["FileSystem","createPath","createPath","get","createPath","get"] [[],["/leet",1],["/leet/code",2],["/leet/code"],["/c/d",1],["/c"]] 输出: [null,true,true,2,false,-1] 解释: FileSystem fileSystem = new FileSystem(); fileSystem.createPath("/leet", 1); // 返回 true fileSystem.createPath("/leet/code", 2); // 返回 true fileSystem.get("/leet/code"); // 返回 2 fileSystem.createPath("/c/d", 1); // 返回 false 因为父路径 "/c" 不存在。 fileSystem.get("/c"); // 返回 -1 因为该路径不存在。
提示:
- 对两个函数的调用次数加起来小于等于
104
2 <= path.length <= 100
1 <= value <= 109
方法一:前缀树
哈希表实现前缀树。
class Trie:
def __init__(self):
self.children = {}
self.v = 0
def insert(self, w, v):
node = self
ps = w.split('/')
for p in ps[1:-1]:
if p not in node.children:
return False
node = node.children[p]
if ps[-1] in node.children:
return False
node.children[ps[-1]] = Trie()
node = node.children[ps[-1]]
node.v = v
return True
def search(self, w):
node = self
for p in w.split('/')[1:]:
if p not in node.children:
return -1
node = node.children[p]
return node.v or -1
class FileSystem:
def __init__(self):
self.trie = Trie()
def createPath(self, path: str, value: int) -> bool:
return self.trie.insert(path, value)
def get(self, path: str) -> int:
return self.trie.search(path)
# Your FileSystem object will be instantiated and called as such:
# obj = FileSystem()
# param_1 = obj.createPath(path,value)
# param_2 = obj.get(path)
class Trie {
Map<String, Trie> children = new HashMap<>();
int v;
boolean insert(String w, int v) {
Trie node = this;
String[] ps = w.split("/");
for (int i = 1; i < ps.length - 1; ++i) {
String p = ps[i];
if (!node.children.containsKey(p)) {
return false;
}
node = node.children.get(p);
}
if (node.children.containsKey(ps[ps.length - 1])) {
return false;
}
node.children.put(ps[ps.length - 1], new Trie());
node = node.children.get(ps[ps.length - 1]);
node.v = v;
return true;
}
int search(String w) {
Trie node = this;
String[] ps = w.split("/");
for (int i = 1; i < ps.length; ++i) {
String p = ps[i];
if (!node.children.containsKey(p)) {
return -1;
}
node = node.children.get(p);
}
return node.v == 0 ? -1 : node.v;
}
}
class FileSystem {
private Trie trie = new Trie();
public FileSystem() {
}
public boolean createPath(String path, int value) {
return trie.insert(path, value);
}
public int get(String path) {
return trie.search(path);
}
}
/**
* Your FileSystem object will be instantiated and called as such:
* FileSystem obj = new FileSystem();
* boolean param_1 = obj.createPath(path,value);
* int param_2 = obj.get(path);
*/
type Trie struct {
children map[string]*Trie
v int
}
func newTrie() *Trie {
m := map[string]*Trie{}
return &Trie{children: m}
}
func (this *Trie) insert(w string, v int) bool {
node := this
ps := strings.Split(w, "/")
for _, p := range ps[1 : len(ps)-1] {
if _, ok := node.children[p]; !ok {
return false
}
node, _ = node.children[p]
}
x := ps[len(ps)-1]
if _, ok := node.children[x]; ok {
return false
}
node.children[x] = newTrie()
node, _ = node.children[x]
node.v = v
return true
}
func (this *Trie) search(w string) int {
node := this
for _, p := range strings.Split(w, "/")[1:] {
if _, ok := node.children[p]; !ok {
return -1
}
node, _ = node.children[p]
}
if node.v == 0 {
return -1
}
return node.v
}
type FileSystem struct {
trie *Trie
}
func Constructor() FileSystem {
return FileSystem{newTrie()}
}
func (this *FileSystem) CreatePath(path string, value int) bool {
return this.trie.insert(path, value)
}
func (this *FileSystem) Get(path string) int {
return this.trie.search(path)
}
/**
* Your FileSystem object will be instantiated and called as such:
* obj := Constructor();
* param_1 := obj.CreatePath(path,value);
* param_2 := obj.Get(path);
*/