Imagine you have a list of words:
['cat', 'ant', 'bro', 'gro']
Using some arbitrary mapping that we construct ourselves {'c'=>'a', 'a'=>'n', 't'=>'t' }
, we can map 'cat' to 'ant', and similarly we can find some arbitrary mapping to convert 'bro' to 'gro'.
This is the idea of finding words that are equivalent. I wrote a function that compares two words, and checks if they are equivalent through a mapping I construct on the fly:
def compareWords(w1, w2):
mapping = {}
for i in xrange(0, len(w1)):
if w1[i] in map:
if mapping[w1[i]] == w2[i]:
continue
else:
return False
else:
mapping[w1[i]] = w2[i]
return True
Example input:
['cat', 'ant', 'bro', 'gro']
Example output:
[['cat','ant'], ['bro', 'gro']]
Using this function on each pair of words in the list to return an output list of lists of equivalent words runs in O(n^2) since every pair will need to be compared. I haven't implemented this part where I use this method above on the input list and generate the output list, since this method isn't the efficient comparison I am looking for. Is there a way to find equivalent words in this input list in O(n) time?
Further Explanation: If I have a list of words, and I want to find all the "equivalent" words, I would need to make the checks in pairs of words. If all letters of the words I am comparing are unique, then another word in the list is only equivalent to this first word if all the letters in the second word are also unique. so abc can be mapped to xyz if xyz is in the list. xyz can be mapped to pqr if xyz is in the list. Given this, abc, xyz, and pqr are all equivalent. This is the kind of grouping I am looking for.