609. Find Duplicate File in System
Получив список paths информации о каталоге, включающий путь к каталогу и все файлы с содержимым в этом каталоге, верните все дубликаты файлов в файловой системе по их путям. Вы можете вернуть ответ в любом порядке. Группа дубликатов состоит как минимум из двух файлов с одинаковым содержимым. Одна строка информации о каталоге во входном списке имеет следующий формат: "root/d1/d2/...
/dm
f1.txt(f1_content) f2.txt(f2_content) ... fn.txt(fn_content)" Это означает, что в каталоге "root/d1/d2/...
/dm
" имеется n файлов (f1.txt, f2.txt ... fn.txt) с содержимым (f1_content, f2_content ... fn_content) соответственно. Обратите внимание, что n >= 1 и m >= 0. Если m = 0, это означает, что каталог является только корневым. На выходе получается список групп дублирующихся путей к файлам. Для каждой группы он содержит все пути к файлам, которые имеют одинаковое содержимое. Путь к файлу - это строка, имеющая следующий формат: "каталог_путь/имя_файла.txt".
Пример:
Input: paths = ["root/a 1.txt(abcd) 2.txt(efgh)","root/c 3.txt(abcd)","root/c/d 4.txt(efgh)","root 4.txt(efgh)"]
Output: [["root/a/2.txt","root/c/d/4.txt","root/4.txt"],["root/a/1.txt","root/c/3.txt"]]
C# решение
сопоставлено/оригиналpublic class Solution {
public IList<IList<string>> FindDuplicate(string[] paths) {
var contentToFilePaths = new Dictionary<string, List<string>>();
foreach (var path in paths) {
var parts = path.Split(new char[] { ' ' });
var root = parts[0];
for (int i = 1; i < parts.Length; i++) {
var fileParts = parts[i].Split(new char[] { '(' });
var fileName = fileParts[0];
var content = fileParts[1].TrimEnd(')');
var filePath = $"{root}/{fileName}";
if (!contentToFilePaths.ContainsKey(content)) {
contentToFilePaths[content] = new List<string>();
}
contentToFilePaths[content].Add(filePath);
}
}
var result = new List<IList<string>>();
foreach (var kvp in contentToFilePaths) {
if (kvp.Value.Count > 1) {
result.Add(kvp.Value);
}
}
return result;
}
}
C++ решение
auto-draft, проверить перед отправкой#include <bits/stdc++.h>
using namespace std;
// Auto-generated C++ draft from the C# solution. Review containers, LINQ and helper types before submit.
class Solution {
public:
public IList<vector<string>> FindDuplicate(vector<string> paths) {
var contentToFilePaths = new unordered_map<string, List<string>>();
foreach (var path in paths) {
var parts = path.Split(new char[] { ' ' });
var root = parts[0];
for (int i = 1; i < parts.size(); i++) {
var fileParts = parts[i].Split(new char[] { '(' });
var fileName = fileParts[0];
var content = fileParts[1].TrimEnd(')');
var filePath = $"{root}/{fileName}";
if (!contentToFilePaths.count(content)) {
contentToFilePaths[content] = new List<string>();
}
contentToFilePaths[content].push_back(filePath);
}
}
var result = new List<vector<string>>();
foreach (var kvp in contentToFilePaths) {
if (kvp.Value.size() > 1) {
result.push_back(kvp.Value);
}
}
return result;
}
}
Java решение
сопоставлено/оригиналimport java.util.*;
public class Solution {
public List<List<String>> findDuplicate(String[] paths) {
Map<String, List<String>> contentToFilePaths = new HashMap<>();
for (String path : paths) {
String[] parts = path.split(" ");
String root = parts[0];
for (int i = 1; i < parts.length; i++) {
String[] fileParts = parts[i].split("\\(");
String fileName = fileParts[0];
String content = fileParts[1].substring(0, fileParts[1].length() - 1);
String filePath = root + "/" + fileName;
contentToFilePaths.computeIfAbsent(content, k -> new ArrayList<>()).add(filePath);
}
}
List<List<String>> result = new ArrayList<>();
for (List<String> filePaths : contentToFilePaths.values()) {
if (filePaths.size() > 1) {
result.add(filePaths);
}
}
return result;
}
}
JavaScript решение
сопоставлено/оригиналfunction findDuplicate(paths) {
const contentToFilePaths = {};
for (const path of paths) {
const parts = path.split(" ");
const root = parts[0];
for (let i = 1; i < parts.length; i++) {
const [fileName, content] = parts[i].split("(");
const filePath = `${root}/${fileName}`;
const contentKey = content.slice(0, -1);
if (!contentToFilePaths[contentKey]) {
contentToFilePaths[contentKey] = [];
}
contentToFilePaths[contentKey].push(filePath);
}
}
return Object.values(contentToFilePaths).filter(paths => paths.length > 1);
}
Python решение
сопоставлено/оригиналdef findDuplicate(paths):
content_to_file_paths = {}
for path in paths:
parts = path.split(" ")
root = parts[0]
for part in parts[1:]:
file_name, content = part.split("(")
content = content[:-1]
file_path = f"{root}/{file_name}"
if content not in content_to_file_paths:
content_to_file_paths[content] = []
content_to_file_paths[content].append(file_path)
return [file_paths for file_paths in content_to_file_paths.values() if len(file_paths) > 1]
Go решение
сопоставлено/оригиналpackage main
import (
"strings"
)
func findDuplicate(paths []string) [][]string {
contentToFilePaths := make(map[string][]string)
for _, path := range paths {
parts := strings.Split(path, " ")
root := parts[0]
for i := 1; i < len(parts); i++ {
fileParts := strings.Split(parts[i], "(")
fileName := fileParts[0]
content := fileParts[1][:len(fileParts[1])-1]
filePath := root + "/" + fileName
contentToFilePaths[content] = append(contentToFilePaths[content], filePath)
}
}
var result [][]string
for _, filePaths := range contentToFilePaths {
if len(filePaths) > 1 {
result = append(result, filePaths)
}
}
return result
}
Algorithm
Пройдите по списку путей, разберите каждый путь и соберите информацию о содержимом файлов и соответствующих им путях.
Используйте словарь для хранения списков путей файлов, сгруппированных по их содержимому.
Пройдите по словарю и соберите группы дубликатов, содержащие как минимум два пути.
😎
Вакансии для этой задачи
Показаны активные вакансии с пересечением по тегам задачи.