Write an O(m*n) LeetCode solution of find-and-replace-pattern that beats 100.00% of users with TypeScript [54ms]
![Cover Image for Write an O(m*n) LeetCode solution of find-and-replace-pattern that beats 100.00% of users with TypeScript [54ms]](/_next/image?url=https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1704027081631%2F29b486d8-5aaa-4d78-ae60-3465846364cf.png%3Fw%3D1600%26h%3D840%26fit%3Dcrop%26crop%3Dentropy%26auto%3Dcompress%2Cformat%26format%3Dwebp&w=3840&q=75)
Try to solve the solution before read this article at: leetcode.com/problems/find-and-replace-pattern
Thoughts:
Transform Words and Pattern:
wordToId
that transforms a word into a pattern-like string:wordToId
to both the pattern
and each word in the words
array.Identify Matching Words:
words
array.pattern
, add the original word to the result
array.Return Matching Words:
result
array containing the words that match the pattern.words
array and m is the length of each word (and the pattern
). This is due to iterating through each word and transforming it character by character.wordToId
and the transformed strings.graph TD
subgraph "findAndReplacePattern function"
Start("Start") --> Transform["Transform pattern using wordToId"]
Transform --> Iterate["Iterate through words array"]
Iterate --Check if word length matches pattern length--> CheckLength{"Check length"}
CheckLength -- No --> End("End")
CheckLength -- Yes --> Transform2["Transform word using wordToId"]
Transform2 --"Compare transformed word with pattern"--> Compare{"Compare pattern"}
Compare -- No --> Iterate
Compare -- Yes --> AddToResult["Add word to result array"]
AddToResult --> Iterate
End(End)
end
function findAndReplacePattern(words: string[], pattern: string): string[] {
const result: string[] = [];
const wordToId = ((w: string) => {
const idGetter = {
hMap: {} as Record<string, number>,
id: 0,
getId() {
return ++this.id
},
reset() {
this.id = 0
this.hMap = {}
}
}
return [...w].map(c => {
if (idGetter.hMap[c]) {
return idGetter.hMap[c]
} else {
idGetter.hMap[c] = idGetter.getId()
return idGetter.hMap[c]
}
}).join('-')
})
const p = wordToId(pattern)
words.forEach(w => {
if (w.length !== pattern.length) return
const id = wordToId(w)
if (p === id) {
result.push(w)
}
})
return result
};
use std::collections::HashMap;
impl Solution {
pub fn find_and_replace_pattern(words: Vec<String>, pattern: String) -> Vec<String> {
let mut result = Vec::new();
fn hash_word(w: &str) -> String {
let mut char_to_id = HashMap::new();
let mut id = 0;
w.chars().map(|c| {
*char_to_id.entry(c).or_insert_with(|| { id += 1; id })
}).map(|id| id.to_string()).collect::<Vec<_>>().join("-")
}
let p = hash_word(&pattern);
for w in words.iter() {
if w.len() != pattern.len() {
continue;
}
if p == hash_word(w) {
result.push(w.clone());
}
}
result
}
}
func findAndReplacePattern(words []string, pattern string) []string {
result := make([]string, 0)
hashWord := func(w string) string {
hMap := map[rune]int{}
id := 0
hashed := make([]string, 0, len(w))
for _, c := range w {
if _, ok := hMap[c]; !ok {
hMap[c] = id
id++
}
hashed = append(hashed, strconv.Itoa(hMap[c]))
}
return strings.Join(hashed, "-")
}
p := hashWord(pattern)
for _, w := range words {
if len(w) != len(pattern) {
continue
}
if p == hashWord(w) {
result = append(result, w)
}
}
return result
}
LeetCode submissions: TypeScript, Rust, Golang.