LeetCode Solutions
737. Sentence Similarity II
Time: $O(\max(|\texttt{sentence1}|, |\texttt{sentence2}|) \cdot |\texttt{similarPairs}|)$ Space: $O(|\texttt{similarPairs}|)$
class Solution {
public:
bool areSentencesSimilarTwo(vector<string>& words1, vector<string>& words2,
vector<vector<string>>& pairs) {
if (words1.size() != words2.size())
return false;
// graph[key] := all similar words of key
unordered_map<string, unordered_set<string>> graph;
for (const vector<string>& pair : pairs) {
graph[pair[1]].insert(pair[0]);
graph[pair[0]].insert(pair[1]);
}
for (int i = 0; i < words1.size(); ++i) {
if (words1[i] == words2[i])
continue;
if (!graph.count(words1[i]))
return false;
if (!dfs(graph, words1[i], words2[i], {}))
return false;
}
return true;
}
private:
bool dfs(const unordered_map<string, unordered_set<string>>& graph,
const string& source, const string& target,
unordered_set<string>&& seen) {
if (graph.at(source).count(target))
return true;
seen.insert(source);
for (const string& child : graph.at(source)) {
if (seen.count(child))
continue;
if (dfs(graph, child, target, move(seen)))
return true;
}
return false;
}
};
class Solution {
public boolean areSentencesSimilarTwo(String[] words1, String[] words2,
List<List<String>> pairs) {
if (words1.length != words2.length)
return false;
// graph[key] := all similar words of key
Map<String, Set<String>> graph = new HashMap<>();
for (List<String> pair : pairs) {
graph.putIfAbsent(pair.get(0), new HashSet<>());
graph.putIfAbsent(pair.get(1), new HashSet<>());
graph.get(pair.get(1)).add(pair.get(0));
graph.get(pair.get(0)).add(pair.get(1));
}
for (int i = 0; i < words1.length; ++i) {
if (words1[i].equals(words2[i]))
continue;
if (!graph.containsKey(words1[i]))
return false;
if (!dfs(graph, words1[i], words2[i], new HashSet<>()))
return false;
}
return true;
}
private boolean dfs(Map<String, Set<String>> graph, final String source, final String target,
Set<String> seen) {
if (graph.get(source).contains(target))
return true;
seen.add(source);
for (final String child : graph.get(source)) {
if (seen.contains(child))
continue;
if (dfs(graph, child, target, seen))
return true;
}
return false;
}
}
class Solution:
def areSentencesSimilarTwo(self, words1: List[str], words2: List[str], pairs: List[List[str]]) -> bool:
if len(words1) != len(words2):
return False
# graph[key] := all similar words of key
graph = defaultdict(set)
for a, b in pairs:
graph[a].add(b)
graph[b].add(a)
def dfs(word1: str, word2: str, seen: set) -> bool:
if word1 in graph[word2]:
return True
seen.add(word1)
for child in graph[word1]:
if child in seen:
continue
if dfs(child, word2, seen):
return True
return False
for word1, word2 in zip(words1, words2):
if word1 == word2:
continue
if word1 not in graph:
return False
if not dfs(word1, word2, set()):
return False
return True