Skip to content

Commit ea9aa78

Browse files
committed
feat: add solutions to lc problem: No.1166
No.1166.Design File System
1 parent 77b5d75 commit ea9aa78

File tree

7 files changed

+556
-128
lines changed

7 files changed

+556
-128
lines changed

solution/1100-1199/1166.Design File System/README.md

+196-42
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,19 @@ fileSystem.get("/c"); // 返回 -1 因为该路径不存在。
6868

6969
**方法一:前缀树**
7070

71-
哈希表实现前缀树。
71+
我们可以使用前缀树来存储路径,每个节点存储一个值,表示该节点对应的路径的值。
72+
73+
定义前缀树的节点结构如下:
74+
75+
- `children`:子节点,使用哈希表存储,键为子节点的路径,值为子节点的引用;
76+
- `v`:当前节点对应的路径的值。
77+
78+
定义前缀树的方法如下:
79+
80+
- `insert(w, v)`:插入路径 $w$,并将其对应的值设为 $v$。如果路径 $w$ 已经存在或其父路径不存在,则返回 `false`,否则返回 `true`。时间复杂度为 $O(|w|)$,其中 $|w|$ 为路径 $w$ 的长度;
81+
- `search(w)`:返回路径 $w$ 对应的值。如果路径 $w$ 不存在,则返回 $-1$。时间复杂度为 $O(|w|)$。
82+
83+
总时间复杂度 $O(\sum_{w \in W}|w|)$,总空间复杂度 $O(\sum_{w \in W}|w|)$,其中 $W$ 为所有插入的路径的集合。
7284

7385
<!-- tabs:start -->
7486

@@ -78,31 +90,29 @@ fileSystem.get("/c"); // 返回 -1 因为该路径不存在。
7890

7991
```python
8092
class Trie:
81-
def __init__(self):
93+
def __init__(self, v: int = -1):
8294
self.children = {}
83-
self.v = 0
95+
self.v = v
8496

85-
def insert(self, w, v):
97+
def insert(self, w: str, v: int) -> bool:
8698
node = self
87-
ps = w.split('/')
99+
ps = w.split("/")
88100
for p in ps[1:-1]:
89101
if p not in node.children:
90102
return False
91103
node = node.children[p]
92104
if ps[-1] in node.children:
93105
return False
94-
node.children[ps[-1]] = Trie()
95-
node = node.children[ps[-1]]
96-
node.v = v
106+
node.children[ps[-1]] = Trie(v)
97107
return True
98108

99-
def search(self, w):
109+
def search(self, w: str) -> int:
100110
node = self
101-
for p in w.split('/')[1:]:
111+
for p in w.split("/")[1:]:
102112
if p not in node.children:
103113
return -1
104114
node = node.children[p]
105-
return node.v or -1
115+
return node.v
106116

107117

108118
class FileSystem:
@@ -131,11 +141,15 @@ class Trie {
131141
Map<String, Trie> children = new HashMap<>();
132142
int v;
133143

144+
Trie(int v) {
145+
this.v = v;
146+
}
147+
134148
boolean insert(String w, int v) {
135149
Trie node = this;
136-
String[] ps = w.split("/");
150+
var ps = w.split("/");
137151
for (int i = 1; i < ps.length - 1; ++i) {
138-
String p = ps[i];
152+
var p = ps[i];
139153
if (!node.children.containsKey(p)) {
140154
return false;
141155
}
@@ -144,30 +158,29 @@ class Trie {
144158
if (node.children.containsKey(ps[ps.length - 1])) {
145159
return false;
146160
}
147-
node.children.put(ps[ps.length - 1], new Trie());
148-
node = node.children.get(ps[ps.length - 1]);
149-
node.v = v;
161+
node.children.put(ps[ps.length - 1], new Trie(v));
150162
return true;
151163
}
152164

153165
int search(String w) {
154166
Trie node = this;
155-
String[] ps = w.split("/");
167+
var ps = w.split("/");
156168
for (int i = 1; i < ps.length; ++i) {
157-
String p = ps[i];
169+
var p = ps[i];
158170
if (!node.children.containsKey(p)) {
159171
return -1;
160172
}
161173
node = node.children.get(p);
162174
}
163-
return node.v == 0 ? -1 : node.v;
175+
return node.v;
164176
}
165177
}
166178

167179
class FileSystem {
168-
private Trie trie = new Trie();
180+
private Trie trie = new Trie(-1);
169181

170182
public FileSystem() {
183+
171184
}
172185

173186
public boolean createPath(String path, int value) {
@@ -187,58 +200,133 @@ class FileSystem {
187200
*/
188201
```
189202

203+
### **C++**
204+
205+
```cpp
206+
class Trie {
207+
public:
208+
unordered_map<string, Trie*> children;
209+
int v;
210+
211+
Trie(int v) {
212+
this->v = v;
213+
}
214+
215+
bool insert(string& w, int v) {
216+
Trie* node = this;
217+
auto ps = split(w, '/');
218+
for (int i = 1; i < ps.size() - 1; ++i) {
219+
auto p = ps[i];
220+
if (!node->children.count(p)) {
221+
return false;
222+
}
223+
node = node->children[p];
224+
}
225+
if (node->children.count(ps.back())) {
226+
return false;
227+
}
228+
node->children[ps.back()] = new Trie(v);
229+
return true;
230+
}
231+
232+
int search(string& w) {
233+
Trie* node = this;
234+
auto ps = split(w, '/');
235+
for (int i = 1; i < ps.size(); ++i) {
236+
auto p = ps[i];
237+
if (!node->children.count(p)) {
238+
return -1;
239+
}
240+
node = node->children[p];
241+
}
242+
return node->v;
243+
}
244+
245+
246+
private:
247+
vector<string> split(string& s, char delim) {
248+
stringstream ss(s);
249+
string item;
250+
vector<string> res;
251+
while (getline(ss, item, delim)) {
252+
res.emplace_back(item);
253+
}
254+
return res;
255+
}
256+
};
257+
258+
class FileSystem {
259+
public:
260+
FileSystem() {
261+
trie = new Trie(-1);
262+
}
263+
264+
bool createPath(string path, int value) {
265+
return trie->insert(path, value);
266+
}
267+
268+
int get(string path) {
269+
return trie->search(path);
270+
}
271+
272+
private:
273+
Trie* trie;
274+
};
275+
276+
/**
277+
* Your FileSystem object will be instantiated and called as such:
278+
* FileSystem* obj = new FileSystem();
279+
* bool param_1 = obj->createPath(path,value);
280+
* int param_2 = obj->get(path);
281+
*/
282+
```
283+
190284
### **Go**
191285
192286
```go
193-
type Trie struct {
194-
children map[string]*Trie
287+
type trie struct {
288+
children map[string]*trie
195289
v int
196290
}
197291
198-
func newTrie() *Trie {
199-
m := map[string]*Trie{}
200-
return &Trie{children: m}
292+
func newTrie(v int) *trie {
293+
return &trie{map[string]*trie{}, v}
201294
}
202295
203-
func (this *Trie) insert(w string, v int) bool {
204-
node := this
296+
func (t *trie) insert(w string, v int) bool {
297+
node := t
205298
ps := strings.Split(w, "/")
206299
for _, p := range ps[1 : len(ps)-1] {
207300
if _, ok := node.children[p]; !ok {
208301
return false
209302
}
210-
node, _ = node.children[p]
303+
node = node.children[p]
211304
}
212-
x := ps[len(ps)-1]
213-
if _, ok := node.children[x]; ok {
305+
if _, ok := node.children[ps[len(ps)-1]]; ok {
214306
return false
215307
}
216-
node.children[x] = newTrie()
217-
node, _ = node.children[x]
218-
node.v = v
308+
node.children[ps[len(ps)-1]] = newTrie(v)
219309
return true
220310
}
221311
222-
func (this *Trie) search(w string) int {
223-
node := this
224-
for _, p := range strings.Split(w, "/")[1:] {
312+
func (t *trie) search(w string) int {
313+
node := t
314+
ps := strings.Split(w, "/")
315+
for _, p := range ps[1:] {
225316
if _, ok := node.children[p]; !ok {
226317
return -1
227318
}
228-
node, _ = node.children[p]
229-
}
230-
if node.v == 0 {
231-
return -1
319+
node = node.children[p]
232320
}
233321
return node.v
234322
}
235323
236324
type FileSystem struct {
237-
trie *Trie
325+
trie *trie
238326
}
239327
240328
func Constructor() FileSystem {
241-
return FileSystem{newTrie()}
329+
return FileSystem{trie: newTrie(-1)}
242330
}
243331
244332
func (this *FileSystem) CreatePath(path string, value int) bool {
@@ -257,6 +345,72 @@ func (this *FileSystem) Get(path string) int {
257345
*/
258346
```
259347

348+
### **TypeScript**
349+
350+
```ts
351+
class Trie {
352+
children: Map<string, Trie>;
353+
v: number;
354+
355+
constructor(v: number) {
356+
this.children = new Map<string, Trie>();
357+
this.v = v;
358+
}
359+
360+
insert(w: string, v: number): boolean {
361+
let node: Trie = this;
362+
const ps = w.split('/').slice(1);
363+
for (let i = 0; i < ps.length - 1; ++i) {
364+
const p = ps[i];
365+
if (!node.children.has(p)) {
366+
return false;
367+
}
368+
node = node.children.get(p)!;
369+
}
370+
if (node.children.has(ps[ps.length - 1])) {
371+
return false;
372+
}
373+
node.children.set(ps[ps.length - 1], new Trie(v));
374+
return true;
375+
}
376+
377+
search(w: string): number {
378+
let node: Trie = this;
379+
const ps = w.split('/').slice(1);
380+
for (const p of ps) {
381+
if (!node.children.has(p)) {
382+
return -1;
383+
}
384+
node = node.children.get(p)!;
385+
}
386+
return node.v;
387+
}
388+
}
389+
390+
class FileSystem {
391+
trie: Trie;
392+
393+
constructor() {
394+
this.trie = new Trie(-1);
395+
}
396+
397+
createPath(path: string, value: number): boolean {
398+
return this.trie.insert(path, value);
399+
}
400+
401+
get(path: string): number {
402+
return this.trie.search(path);
403+
}
404+
}
405+
406+
/**
407+
* Your FileSystem object will be instantiated and called as such:
408+
* var obj = new FileSystem()
409+
* var param_1 = obj.createPath(path,value)
410+
* var param_2 = obj.get(path)
411+
*/
412+
```
413+
260414
### **...**
261415

262416
```

0 commit comments

Comments
 (0)