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 <= 300
pattern
contains only lower-case English letters.1 <= s.length <= 3000
s
contains only lowercase English letters and spaces' '
.s
does not contain any leading or trailing spaces.- All the words in
s
are 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
s
is a space-separated English word, it is very regular. You can use regular expressions to parse thes
string and match each individual word. In the callback function of thereplace
method, each word is processed. - We construct a map to record each word and the corresponding position of the
pattern
letter. 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
pattern
letter 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 thepattern
letter 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
replace
callback function, So at the end, make sure that the lengths ofs
andpattern
need 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