class Solution:
def areSentencesSimilarTwo(self, words1, words2, pairs):
if len(words1) != len(words2):
return False
from collections import defaultdict
parent = {}
def find(x):
if x != parent.setdefault(x, x):
parent[x] = find(parent[x])
return parent[x]
def union(x, y):
parent[find(x)] = find(y)
for a, b in pairs:
union(a, b)
for w1, w2 in zip(words1, words2):
if w1 == w2:
continue
if find(w1) != find(w2):
return False
return True
class Solution {
public:
unordered_map<string, string> parent;
string find(string x) {
if (parent.find(x) == parent.end()) parent[x] = x;
if (parent[x] != x) parent[x] = find(parent[x]);
return parent[x];
}
void unite(string x, string y) {
parent[find(x)] = find(y);
}
bool areSentencesSimilarTwo(vector<string>& words1, vector<string>& words2, vector<vector<string>>& pairs) {
if (words1.size() != words2.size()) return false;
for (auto& p : pairs) {
unite(p[0], p[1]);
}
for (int i = 0; i < words1.size(); ++i) {
if (words1[i] == words2[i]) continue;
if (find(words1[i]) != find(words2[i])) return false;
}
return true;
}
};
class Solution {
Map<String, String> parent = new HashMap<>();
private String find(String x) {
if (!parent.containsKey(x)) parent.put(x, x);
if (!parent.get(x).equals(x)) parent.put(x, find(parent.get(x)));
return parent.get(x);
}
private void union(String x, String y) {
parent.put(find(x), find(y));
}
public boolean areSentencesSimilarTwo(String[] words1, String[] words2, List<List<String>> pairs) {
if (words1.length != words2.length) return false;
for (List<String> p : pairs) {
union(p.get(0), p.get(1));
}
for (int i = 0; i < words1.length; ++i) {
if (words1[i].equals(words2[i])) continue;
if (!find(words1[i]).equals(find(words2[i]))) return false;
}
return true;
}
}
var areSentencesSimilarTwo = function(words1, words2, pairs) {
if (words1.length !== words2.length) return false;
const parent = {};
function find(x) {
if (!(x in parent)) parent[x] = x;
if (parent[x] !== x) parent[x] = find(parent[x]);
return parent[x];
}
function union(x, y) {
parent[find(x)] = find(y);
}
for (let [a, b] of pairs) {
union(a, b);
}
for (let i = 0; i < words1.length; i++) {
if (words1[i] === words2[i]) continue;
if (find(words1[i]) !== find(words2[i])) return false;
}
return true;
};
words1
and words2
, determine if they are similar. Two sentences are similar if each pair of corresponding words are either the same, or they are similar according to a given list of word pairs pairs
. Similarity is transitive: if "a" is similar to "b", and "b" is similar to "c", then "a" is similar to "c". Also, similarity is symmetric. Each word pair in pairs
represents a direct similarity.
words1
and words2
) must be of the same length to be considered similar.pairs
is a two-element list of strings.words1
and words2
against the list of pairs, but this only works for direct similarity. The challenge is the transitive property: "a" similar to "b" and "b" similar to "c" means "a" is similar to "c". This forms a graph where words are connected if they are similar, and we want to see if two words are in the same connected component.
(a, b)
in pairs
, union them together so they belong to the same group.find
to flatten the structure for faster future queries.i
, if words1[i]
and words2[i]
are the same, continue.words1
and words2
differ, immediately return false.words1 = ["great", "acting", "skills"]
words2 = ["fine", "drama", "talent"]
pairs = [["great", "good"], ["fine", "good"], ["acting","drama"], ["skills","talent"]]
True
.