71
71
72
72
** 方法一:哈希表**
73
73
74
- ` key ` 为文件内容,` value ` 为文件路径数组,最后取出所有长度大于 1 的 ` value ` 即答案。
74
+ 我们创建哈希表 ` d ` ,其中键是文件内容,值是具有相同内容的文件路径列表。
75
+
76
+ 遍历 ` paths ` ,我们处理出每个文件的路径和内容,然后将其添加到哈希表 ` d ` 中。
77
+
78
+ 最后,我们返回哈希表 ` d ` 中所有具有多个文件路径的值。
79
+
80
+ 时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为 ` paths ` 的长度。
75
81
76
82
<!-- tabs:start -->
77
83
82
88
``` python
83
89
class Solution :
84
90
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 ]
99
99
```
100
100
101
101
### ** Java**
@@ -105,92 +105,104 @@ class Solution:
105
105
``` java
106
106
class Solution {
107
107
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);
118
116
}
119
117
}
120
-
121
118
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 );
125
122
}
126
123
}
127
124
return ans;
128
125
}
129
126
}
130
127
```
131
128
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
+
132
166
### ** Go**
133
167
134
168
``` go
135
169
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)
144
178
}
145
179
}
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)
151
184
}
152
185
}
153
186
return ans
154
187
}
155
188
```
156
189
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 );
167
202
}
168
- return result;
169
203
}
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
+ }
194
206
```
195
207
196
208
### ** ...**
0 commit comments