609. Find Duplicate File in System

LeetCode medium оригинал: C# #csharp #hash-table #leetcode #medium #search #string

Получив список 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

Пройдите по списку путей, разберите каждый путь и соберите информацию о содержимом файлов и соответствующих им путях.

Используйте словарь для хранения списков путей файлов, сгруппированных по их содержимому.

Пройдите по словарю и соберите группы дубликатов, содержащие как минимум два пути.

😎

Вакансии для этой задачи

Показаны активные вакансии с пересечением по тегам задачи.

Все вакансии
Активных вакансий пока нет.