Skip to content

Commit 3cc2400

Browse files
committed
feat: add solutions to lc problem: No.0609
No.0609.Find Duplicate File in System
1 parent bb2782c commit 3cc2400

File tree

7 files changed

+240
-221
lines changed

7 files changed

+240
-221
lines changed

solution/0600-0699/0609.Find Duplicate File in System/README.md

Lines changed: 89 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,13 @@
7171

7272
**方法一:哈希表**
7373

74-
`key` 为文件内容,`value` 为文件路径数组,最后取出所有长度大于 1 的 `value` 即答案。
74+
我们创建哈希表 `d`,其中键是文件内容,值是具有相同内容的文件路径列表。
75+
76+
遍历 `paths`,我们处理出每个文件的路径和内容,然后将其添加到哈希表 `d` 中。
77+
78+
最后,我们返回哈希表 `d` 中所有具有多个文件路径的值。
79+
80+
时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为 `paths` 的长度。
7581

7682
<!-- tabs:start -->
7783

@@ -82,20 +88,14 @@
8288
```python
8389
class Solution:
8490
def findDuplicate(self, paths: List[str]) -> List[List[str]]:
85-
m = defaultdict(list)
86-
for path in paths:
87-
a = path.split(" ")
88-
for i in range(1, len(a)):
89-
j = a[i].find("(")
90-
content = a[i][j + 1 : -1]
91-
name = a[0] + "/" + a[i][:j]
92-
m[content].append(name)
93-
94-
ans = []
95-
for names in m.values():
96-
if len(names) > 1:
97-
ans.append(names)
98-
return ans
91+
d = defaultdict(list)
92+
for p in paths:
93+
ps = p.split()
94+
for f in ps[1:]:
95+
i = f.find('(')
96+
name, content = f[:i], f[i + 1: -1]
97+
d[content].append(ps[0] + '/' + name)
98+
return [v for v in d.values() if len(v) > 1]
9999
```
100100

101101
### **Java**
@@ -105,92 +105,104 @@ class Solution:
105105
```java
106106
class Solution {
107107
public List<List<String>> findDuplicate(String[] paths) {
108-
Map<String, List<String>> map = new HashMap<>();
109-
for (String path : paths) {
110-
String[] a = path.split(" ");
111-
for (int i = 1; i < a.length; i++) {
112-
int j = a[i].indexOf('(');
113-
String content = a[i].substring(j + 1, a[i].length() - 1);
114-
String name = a[0] + '/' + a[i].substring(0, j);
115-
List<String> list = map.getOrDefault(content, new ArrayList<>());
116-
list.add(name);
117-
map.put(content, list);
108+
Map<String, List<String>> d = new HashMap<>();
109+
for (String p : paths) {
110+
String[] ps = p.split(" ");
111+
for (int i = 1; i < ps.length; ++i) {
112+
int j = ps[i].indexOf('(');
113+
String content = ps[i].substring(j + 1, ps[i].length() - 1);
114+
String name = ps[0] + '/' + ps[i].substring(0, j);
115+
d.computeIfAbsent(content, k -> new ArrayList<>()).add(name);
118116
}
119117
}
120-
121118
List<List<String>> ans = new ArrayList<>();
122-
for (List<String> names : map.values()) {
123-
if (names.size() > 1) {
124-
ans.add(names);
119+
for (var e : d.values()) {
120+
if (e.size() > 1) {
121+
ans.add(e);
125122
}
126123
}
127124
return ans;
128125
}
129126
}
130127
```
131128

129+
### **C++**
130+
131+
```cpp
132+
class Solution {
133+
public:
134+
vector<vector<string>> findDuplicate(vector<string>& paths) {
135+
unordered_map<string, vector<string>> d;
136+
for (auto& p : paths) {
137+
auto ps = split(p, ' ');
138+
for (int i = 1; i < ps.size(); ++i) {
139+
int j = ps[i].find('(');
140+
auto content = ps[i].substr(j + 1, ps[i].size() - j - 2);
141+
auto name = ps[0] + '/' + ps[i].substr(0, j);
142+
d[content].push_back(name);
143+
}
144+
}
145+
vector<vector<string>> ans;
146+
for (auto& [_, e] : d) {
147+
if (e.size() > 1) {
148+
ans.push_back(e);
149+
}
150+
}
151+
return ans;
152+
}
153+
154+
vector<string> split(string& s, char c) {
155+
vector<string> res;
156+
stringstream ss(s);
157+
string t;
158+
while (getline(ss, t, c)) {
159+
res.push_back(t);
160+
}
161+
return res;
162+
}
163+
};
164+
```
165+
132166
### **Go**
133167

134168
```go
135169
func findDuplicate(paths []string) [][]string {
136-
m := make(map[string][]string)
137-
for _, path := range paths {
138-
a := strings.Split(path, " ")
139-
for i := 1; i < len(a); i++ {
140-
j := strings.Index(a[i], "(")
141-
content := a[i][j+1 : len(a[i])-1]
142-
name := a[0] + "/" + a[i][:j]
143-
m[content] = append(m[content], name)
170+
d := map[string][]string{}
171+
for _, p := range paths {
172+
ps := strings.Split(p, " ")
173+
for i := 1; i < len(ps); i++ {
174+
j := strings.IndexByte(ps[i], '(')
175+
content := ps[i][j+1 : len(ps[i])-1]
176+
name := ps[0] + "/" + ps[i][:j]
177+
d[content] = append(d[content], name)
144178
}
145179
}
146-
147-
var ans [][]string
148-
for _, names := range m {
149-
if len(names) > 1 {
150-
ans = append(ans, names)
180+
ans := [][]string{}
181+
for _, e := range d {
182+
if len(e) > 1 {
183+
ans = append(ans, e)
151184
}
152185
}
153186
return ans
154187
}
155188
```
156189

157-
### **C++**
158-
159-
```cpp
160-
class Solution {
161-
vector<string> split(const string& s, char delim) {
162-
vector<string> result;
163-
stringstream ss(s);
164-
string item;
165-
while (getline(ss, item, delim)) {
166-
result.push_back(item);
190+
### **TypeScript**
191+
192+
```ts
193+
function findDuplicate(paths: string[]): string[][] {
194+
const d = new Map<string, string[]>();
195+
for (const p of paths) {
196+
const [root, ...fs] = p.split(' ');
197+
for (const f of fs) {
198+
const [name, content] = f.split(/\(|\)/g).filter(Boolean);
199+
const t = d.get(content) ?? [];
200+
t.push(root + '/' + name);
201+
d.set(content, t);
167202
}
168-
return result;
169203
}
170-
171-
public:
172-
vector<vector<string>> findDuplicate(vector<string>& paths) {
173-
unordered_map<string, vector<string>> m;
174-
for (auto& path : paths) {
175-
auto a = split(path, ' ');
176-
for (int i = 1; i < a.size(); ++i) {
177-
int j = a[i].find('(');
178-
auto content = a[i].substr(j + 1, a[i].size() - j - 2);
179-
auto name = a[0] + '/' + a[i].substr(0, j);
180-
if (m.find(content) == m.end()) {
181-
m[content] = vector<string>();
182-
}
183-
m[content].emplace_back(name);
184-
}
185-
}
186-
187-
vector<vector<string>> ans;
188-
for (auto& [_, names] : m) {
189-
if (names.size() > 1) ans.emplace_back(names);
190-
}
191-
return ans;
192-
}
193-
};
204+
return [...d.values()].filter(e => e.length > 1);
205+
}
194206
```
195207

196208
### **...**

0 commit comments

Comments
 (0)