We can represent a sentence as an array of strings, for example, sentence = ["I","am","happy","today"]. Two sentences are similar if we can determine if one sentence can be obtained from another by performing zero or more word replacements.
For example, sentence1 = ["I","am","happy","today"] and sentence2 = ["I","am","sad","today"] are similar if the relationship happy is similar to sad is known.
You are given two sentences sentence1 and sentence2 represented as strings, and a list of similar word pairs pairs, where each pair indicates the two words are similar.
Return true if sentence1 and sentence2 are similar, or false if they are not similar.
Example 1:
Input: sentence1 = ["I","am","happy","today"], sentence2 = ["I","am","happy","today"], pairs = [] Output: true Explanation: sentence1 and sentence2 are exactly the same, so they are similar.
Example 2:
Input: sentence1 = ["I","am","happy","today"], sentence2 = ["I","am","sad","today"], pairs = [["happy","sad"],["sad","happy"]] Output: true Explanation: The words happy and sad are similar.
Example 3:
Input: sentence1 = ["I","am","happy","today"], sentence2 = ["I","am","mad","today"], pairs = [["happy","sad"],["sad","happy"]] Output: false Explanation: The words happy and mad are not similar.
Constraints:
1 <= sentence1.length, sentence2.length <= 10001 <= sentence1[i].length, sentence2[i].length <= 20sentence1[i] and sentence2[i] consist of lower-case and upper-case English letters.0 <= pairs.length <= 20000 <= pairs[i].length == 21 <= pairs[i][0].length, pairs[i][1].length <= 20pairs[i][0] and pairs[i][1] consist of lower-case and upper-case English letters.When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The brute force method for checking if two sentences are similar involves checking every possible way words can be related based on the given word pairs. We explore all connections between words to see if a path exists proving the sentences are similar.
Here's how the algorithm would work step-by-step:
def are_sentences_similar(sentence1, sentence2, word_pairs):
if len(sentence1) != len(sentence2):
return False
for i in range(len(sentence1)):
word1 = sentence1[i]
word2 = sentence2[i]
if word1 == word2:
continue
found = False
if (word1, word2) in word_pairs or (word2, word1) in word_pairs:
continue
# Need to explore possible connections between words
def find_path(start_word, end_word, visited):
if start_word == end_word:
return True
visited.add(start_word)
for pair in word_pairs:
if pair[0] == start_word and pair[1] not in visited:
if find_path(pair[1], end_word, visited):
return True
elif pair[1] == start_word and pair[0] not in visited:
if find_path(pair[0], end_word, visited):
return True
return False
# Check if there is a chain of links connecting the words
if not find_path(word1, word2, set()):
return False
#If all pairs are similar, then return True
return TrueThe efficient approach treats words as connected components in a graph. We determine if two sentences are similar by checking if their corresponding words are connected in the graph, implying a path of similarity exists between them.
Here's how the algorithm would work step-by-step:
def are_sentences_similar_two(sentence1: list[str], sentence2: list[str], similar_pairs: list[list[str]]) -> bool:
if len(sentence1) != len(sentence2):
return False
word_to_component = {}
component_id = 0
def find(word):
if word not in word_to_component:
word_to_component[word] = word
if word_to_component[word] != word:
word_to_component[word] = find(word_to_component[word])
return word_to_component[word]
def union(word1, word2):
root1 = find(word1)
root2 = find(word2)
if root1 != root2:
word_to_component[root1] = root2
# Build the connected components based on similar pairs
for word1, word2 in similar_pairs:
union(word1, word2)
# Check if corresponding words belong to the same component
for i in range(len(sentence1)):
if find(sentence1[i]) != find(sentence2[i]):
return False
return True| Case | How to Handle |
|---|---|
| sentences1 or sentences2 is null or empty | Return true if both are null or empty; otherwise, return false if only one is null/empty. |
| words1 or words2 within pairs is null or empty | Treat a null or empty word as unequal to any other word, including other null/empty words. |
| pairs is null or empty | If pairs is null or empty, return sentences1.equals(sentences2), performing direct string comparison. |
| sentences1 and sentences2 have different lengths | Return false immediately as sentences of different lengths cannot be similar. |
| A large number of pairs leading to a large graph | Use an efficient data structure (e.g., HashMap) for graph representation and path finding to avoid exceeding time limits. |
| Cycles in the pairs relationship | The path finding algorithm (e.g., DFS or BFS) should correctly handle cycles without infinite loops by tracking visited nodes. |
| pairs contains duplicate relationships | The algorithm should overwrite duplicate pairs, only retaining the last definition of a similarity. |
| Integer overflow potential with large strings or many pairs | The solution should avoid calculations that could lead to integer overflow or use appropriate data types (e.g., long) if overflow is unavoidable. |