472. Concatenated Words
Дан 배열 строк words (без дубликатов). return все составные слова из данного списка слов.
Составное слово определяется как 문자열, которая полностью состоит как минимум из двух более коротких слов (не обязательно различных) из данного 배열а.
예제:
Input: words = ["cat","cats","catsdogcats","dog","dogcatsdog","hippopotamuses","rat","ratcatdogcat"]
Output: ["catsdogcats","dogcatsdog","ratcatdogcat"]
Explanation: "catsdogcats" can be concatenated by "cats", "dog" and "cats";
"dogcatsdog" can be concatenated by "dog", "cats" and "dog";
"ratcatdogcat" can be concatenated by "rat", "cat", "dog" and "cat".
C# 해법
매칭됨/원본using System;
using System.Collections.Generic;
public class Solution {
private bool Dfs(string word, int length, bool[] visited, HashSet<string> dictionary) {
if (length == word.Length) {
return true;
}
if (visited[length]) {
return false;
}
visited[length] = true;
for (int i = word.Length - (length == 0 ? 1 : 0); i > length; --i) {
if (dictionary.Contains(word.Substring(length, i - length)) &&
Dfs(word, i, visited, dictionary)) {
return true;
}
}
return false;
}
public IList<string> FindAllConcatenatedWordsInADict(string[] words) {
HashSet<string> dictionary = new HashSet<string>(words);
List<string> answer = new List<string>();
foreach (string word in words) {
bool[] visited = new bool[word.Length];
if (Dfs(word, 0, visited, dictionary)) {
answer.Add(word);
}
}
return answer;
}
}
C++ 해법
자동 초안, 제출 전 검토#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:
private bool Dfs(string word, int length, bool[] visited, HashSet<string> dictionary) {
if (length == word.size()) {
return true;
}
if (visited[length]) {
return false;
}
visited[length] = true;
for (int i = word.size() - (length == 0 ? 1 : 0); i > length; --i) {
if (dictionary.Contains(word.Substring(length, i - length)) &&
Dfs(word, i, visited, dictionary)) {
return true;
}
}
return false;
}
public vector<string> FindAllConcatenatedWordsInADict(vector<string> words) {
HashSet<string> dictionary = new HashSet<string>(words);
List<string> answer = new List<string>();
foreach (string word in words) {
bool[] visited = new bool[word.size()];
if (Dfs(word, 0, visited, dictionary)) {
answer.push_back(word);
}
}
return answer;
}
}
Java 해법
매칭됨/원본import java.util.*;
public class Solution {
private boolean dfs(String word, int length, boolean[] visited, Set<String> dictionary) {
if (length == word.length()) {
return true;
}
if (visited[length]) {
return false;
}
visited[length] = true;
for (int i = word.length() - (length == 0 ? 1 : 0); i > length; --i) {
if (dictionary.contains(word.substring(length, i)) && dfs(word, i, visited, dictionary)) {
return true;
}
}
return false;
}
public List<String> findAllConcatenatedWordsInADict(String[] words) {
Set<String> dictionary = new HashSet<>(Arrays.asList(words));
List<String> answer = new ArrayList<>();
for (String word : words) {
boolean[] visited = new boolean[word.length()];
if (dfs(word, 0, visited, dictionary)) {
answer.add(word);
}
}
return answer;
}
}
JavaScript 해법
매칭됨/원본class Solution {
dfs(word, length, visited, dictionary) {
if (length === word.length) {
return true;
}
if (visited[length]) {
return false;
}
visited[length] = true;
for (let i = word.length - (length === 0 ? 1 : 0); i > length; i--) {
if (dictionary.has(word.slice(length, i)) && this.dfs(word, i, visited, dictionary)) {
return true;
}
}
return false;
}
findAllConcatenatedWordsInADict(words) {
const dictionary = new Set(words);
const answer = [];
for (const word of words) {
const visited = Array(word.length).fill(false);
if (this.dfs(word, 0, visited, dictionary)) {
answer.push(word);
}
}
return answer;
}
}
// Example usage
const solution = new Solution();
const words = ["cat", "cats", "catsdogcats", "dog", "dogcatsdog", "hippopotamuses", "rat", "ratcatdogcat"];
console.log(solution.findAllConcatenatedWordsInADict(words));
Python 해법
매칭됨/원본class Solution:
def dfs(self, word, length, visited, dictionary):
if length == len(word):
return True
if visited[length]:
return False
visited[length] = True
for i in range(len(word) - (1 if length == 0 else 0), length, -1):
if word[length:i] in dictionary and self.dfs(word, i, visited, dictionary):
return True
return False
def findAllConcatenatedWordsInADict(self, words):
dictionary = set(words)
answer = []
for word in words:
visited = [False] * len(word)
if self.dfs(word, 0, visited, dictionary):
answer.append(word)
return answer
Go 해법
매칭됨/원본package main
import (
"strings"
)
type Solution struct{}
func (s Solution) dfs(word string, length int, visited []bool, dictionary map[string]bool) bool {
if length == len(word) {
return true
}
if visited[length] {
return false
}
visited[length] = true
for i := len(word) - 1; i > length; i-- {
if dictionary[word[length:i]] && s.dfs(word, i, visited, dictionary) {
return true
}
}
return false
}
func (s Solution) findAllConcatenatedWordsInADict(words []string) []string {
dictionary := make(map[string]bool)
for _, word := range words {
dictionary[word] = true
}
var answer []string
for _, word := range words {
visited := make([]bool, len(word))
if s.dfs(word, 0, visited, dictionary) {
answer = append(answer, word)
}
}
return answer
}
func main() {
solution := Solution{}
words := []string{"cat", "cats", "catsdogcats", "dog", "dogcatsdog", "hippopotamuses", "rat", "ratcatdogcat"}
result := solution.findAllConcatenatedWordsInADict(words)
for _, word := range result {
println(word)
}
}
Algorithm
Для каждого слова в списке:
Построить неявный 그래프, в котором узлы представляют индексы символов в слове, а ребра представляют возможность перехода от одного индекса к другому, если substring между ними является словом из списка.
Использовать Depth-first search (DFS) для проверки, можно ли достигнуть узел с индексом word.length от узла с индексом 0 в 그래프е.
Если узел word.length достижим от узла 0, добавить слово в ответ.
😎
Vacancies for this task
활성 채용 with overlapping task tags are 표시됨.