LeetCode Notes: Word Pattern
Question
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.
Example 1:
Input: pattern = "abba", s = "dog cat cat dog"
Output: true
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 <= 300patterncontains only lower-case English letters.1 <= s.length <= 3000scontains only lowercase English letters and spaces' '.sdoes not contain any leading or trailing spaces.- All the words in
sare separated by a single space.
Solution
Analysis:
The general idea is to divide the string into arrays and then traverse the processing. Here we use a new method-regular expressions.
- Because the string
sis a space-separated English word, it is very regular. You can use regular expressions to parse thesstring and match each individual word. In the callback function of thereplacemethod, each word is processed. - We construct a map to record each word and the corresponding position of the
patternletter. We add a prefix to the word to prevent letter conflicts inpattern, because a word may also be a letter. - For each word processed, we need to judge if the word or
patternletter has appeared before, whether the current corresponding value is consistent with the last time it appeared, and once it is inconsistent, the rule is not followed. Here you need to judge the word and thepatternletter at the same time to ensure a true two-way connection. - Finally deal with a special case, if there is only one word, because there is not enough comparison, we cannot find the problem inside the
replacecallback function, So at the end, make sure that the lengths ofsandpatternneed to be the same.
Code:
/**
* @param {string} pattern
* @param {string} s
* @return {boolean}
*/
var wordPattern = function (pattern, s) {
var count = 0;
var map = new Map();
var flag = true;
var rr = s.replace(/\b(?=\S)(\S*)/g, function ($0) {
// Follow the replace match of s to get the corresponding pattern letter
let p = pattern[count++];
// For return value
let r = p + $0;
// 1. Both p and "$" + $0 need to be judged
// get(p):'aaaa':'dog cat cat dog'
// get('$' + $0):'abba':'dog dog dog dog'
// 2. Add a prefix'$' + $0 to solve 'abc':'c b a'
if (
(map.has(p) && map.get(p) !== $0) ||
(map.has("$" + $0) && map.get("$" + $0) !== p)
) {
flag = false;
} else {
map.set(p, $0);
map.set("$" + $0, p);
}
return r;
});
// 3. The length of pattern must be equal to the length of s, solve 'jquery':'jquery'
return flag && rr.split(" ").length === pattern.length;
};

Comments