Problem Statement
Word Pattern
You get a short pattern of letters like "abba", and a sentence of words like "dog cat cat dog". The question is: do the words follow the same shape as the letters? In "abba" the first and last letters are the same, and the two middle letters are the same. So the words have to match that, the first and last word the same, and the two middle words the same. There is one more rule. The matching has to be a bijection. A bijection means a strict one-to-one pairing, each letter sticks to exactly one word, and each word sticks to exactly one letter, with no two letters allowed to share the same word. So we keep two lookup tables (called maps), one going each direction, to make sure the pairing stays clean both ways. A map is just a labeled box, you put in a key (like the letter 'a') and it remembers the value (like the word "dog"), so you can ask it later "what did 'a' point to?". This is the same idea as the Isomorphic Strings problem, except here we pair letters with whole words instead of with single characters.
Signals to notice
Brute force first
Try all mappings — O(n!).
The key insight
Two maps: pattern char → word AND word → pattern char. Check consistency at each position. O(n × m) where m is average word length.
Trace it on pattern="abba", s="dog cat cat dog"
words=[dog,cat,cat,dog], len 4 == len(pattern) 4 -> continue; maps empty
i=0 (a,dog): a unseen, dog unseen -> charToWord={a:dog}, wordToChar={dog:a}
i=1 (b,cat): b unseen, cat unseen -> charToWord={a:dog,b:cat}, wordToChar={dog:a,cat:b}
i=2 (b,cat): charToWord[b]=cat==cat ok, wordToChar[cat]=b==b ok -> no change
i=3 (a,dog): charToWord[a]=dog==dog ok, wordToChar[dog]=a==a ok -> no change
loop ends, all consistent -> return trueWhat must stay true
Same as isomorphic strings but with characters and words. The mapping must be bijective — each pattern char maps to exactly one word and vice versa.
Shape of the loop
words = split(s)
if len(pattern) != len(words): return false
charToWord = {}, wordToChar = {}
for (ch, word) in zip(pattern, words):
if (ch in charToWord and charToWord[ch] != word): return false
if (word in wordToChar and wordToChar[word] != ch): return false
charToWord[ch] = word; wordToChar[word] = ch
return truePseudocode only — the full worked solution lives in the Solution tab.
Easy way to go wrong
Only checking one direction — 'a b' matching 'cc cc' requires both directions to detect the inconsistency.