Mutating counts without cleanup
Wrong move: Zero-count keys stay in map and break distinct/count constraints.
Usually fails on: Window/map size checks are consistently off by one.
Fix: Delete keys when count reaches zero.
Build confidence with an intuition-first walkthrough focused on hash map fundamentals.
Given a pattern and a string s, find if s follows the same pattern.
Here follow means a full match, such that there is a bijection between a letter in pattern and a non-empty word in s. Specifically:
pattern maps to exactly one unique word in s.s maps to exactly one letter in pattern.Example 1:
Input: pattern = "abba", s = "dog cat cat dog"
Output: true
Explanation:
The bijection can be established as:
'a' maps to "dog".'b' maps to "cat".Example 2:
Input: pattern = "abba", s = "dog cat cat fish"
Output: false
Example 3:
Input: pattern = "aaaa", s = "dog cat cat dog"
Output: false
Constraints:
1 <= pattern.length <= 300pattern contains only lower-case English letters.1 <= s.length <= 3000s contains only lowercase English letters and spaces ' '.s does not contain any leading or trailing spaces.s are separated by a single space.Problem summary: Given a pattern and a string s, find if s follows the same pattern. Here follow means a full match, such that there is a bijection between a letter in pattern and a non-empty word in s. Specifically: Each letter in pattern maps to exactly one unique word in s. Each unique word in s maps to exactly one letter in pattern. No two letters map to the same word, and no two words map to the same letter.
Start with the most direct exhaustive search. That gives a correctness anchor before optimizing.
Pattern signal: Hash Map
"abba" "dog cat cat dog"
"abba" "dog cat cat fish"
"aaaa" "dog cat cat dog"
isomorphic-strings)word-pattern-ii)find-and-replace-pattern)Source-backed implementations are provided below for direct study and interview prep.
// Accepted solution for LeetCode #290: Word Pattern
class Solution {
public boolean wordPattern(String pattern, String s) {
String[] ws = s.split(" ");
if (pattern.length() != ws.length) {
return false;
}
Map<Character, String> d1 = new HashMap<>();
Map<String, Character> d2 = new HashMap<>();
for (int i = 0; i < ws.length; ++i) {
char a = pattern.charAt(i);
String b = ws[i];
if (!d1.getOrDefault(a, b).equals(b) || d2.getOrDefault(b, a) != a) {
return false;
}
d1.put(a, b);
d2.put(b, a);
}
return true;
}
}
// Accepted solution for LeetCode #290: Word Pattern
func wordPattern(pattern string, s string) bool {
ws := strings.Split(s, " ")
if len(ws) != len(pattern) {
return false
}
d1 := map[rune]string{}
d2 := map[string]rune{}
for i, a := range pattern {
b := ws[i]
if v, ok := d1[a]; ok && v != b {
return false
}
if v, ok := d2[b]; ok && v != a {
return false
}
d1[a] = b
d2[b] = a
}
return true
}
# Accepted solution for LeetCode #290: Word Pattern
class Solution:
def wordPattern(self, pattern: str, s: str) -> bool:
ws = s.split()
if len(pattern) != len(ws):
return False
d1 = {}
d2 = {}
for a, b in zip(pattern, ws):
if (a in d1 and d1[a] != b) or (b in d2 and d2[b] != a):
return False
d1[a] = b
d2[b] = a
return True
// Accepted solution for LeetCode #290: Word Pattern
use std::collections::HashMap;
impl Solution {
pub fn word_pattern(pattern: String, s: String) -> bool {
let cs1: Vec<char> = pattern.chars().collect();
let cs2: Vec<&str> = s.split_whitespace().collect();
let n = cs1.len();
if n != cs2.len() {
return false;
}
let mut map1 = HashMap::new();
let mut map2 = HashMap::new();
for i in 0..n {
let c = cs1[i];
let s = cs2[i];
if !map1.contains_key(&c) {
map1.insert(c, i);
}
if !map2.contains_key(&s) {
map2.insert(s, i);
}
if map1.get(&c) != map2.get(&s) {
return false;
}
}
true
}
}
// Accepted solution for LeetCode #290: Word Pattern
function wordPattern(pattern: string, s: string): boolean {
const ws = s.split(' ');
if (pattern.length !== ws.length) {
return false;
}
const d1 = new Map<string, string>();
const d2 = new Map<string, string>();
for (let i = 0; i < pattern.length; ++i) {
const a = pattern[i];
const b = ws[i];
if (d1.has(a) && d1.get(a) !== b) {
return false;
}
if (d2.has(b) && d2.get(b) !== a) {
return false;
}
d1.set(a, b);
d2.set(b, a);
}
return true;
}
Use this to step through a reusable interview workflow for this problem.
For each element, scan the rest of the array looking for a match. Two nested loops give n × (n−1)/2 comparisons = O(n²). No extra space since we only use loop indices.
One pass through the input, performing O(1) hash map lookups and insertions at each step. The hash map may store up to n entries in the worst case. This is the classic space-for-time tradeoff: O(n) extra memory eliminates an inner loop.
Review these before coding to avoid predictable interview regressions.
Wrong move: Zero-count keys stay in map and break distinct/count constraints.
Usually fails on: Window/map size checks are consistently off by one.
Fix: Delete keys when count reaches zero.