一、题目描述
给定一种规律 pattern 和一个字符串 s ,判断 s 是否遵循相同的规律。
这里的 遵循 指完全匹配,例如, pattern 里的每个字母和字符串 s ****中的每个非空单词之间存在着双向连接的对应规律。
示例1:
输入: pattern = "abba", s = "dog cat cat dog"
输出: true
示例 2:
输入: pattern = "abba", s = "dog cat cat fish"
输出: false
示例 3:
输入: pattern = "aaaa", s = "dog cat cat dog"
输出: false
提示:
1 <= pattern.length <= 300pattern只包含小写英文字母1 <= s.length <= 3000s只包含小写英文字母和' 's不包含 任何前导或尾随对空格s中每个单词都被 单个空格 分隔
二、思路分析
主要思路是通过建立两个 Map 对象来处理模式 pattern 和字符串 s 之间的映射关系,然后检查是否满足一一对应的规则
- 检查
mp是否已经包含了pattern[i]。如果没有包含,说明这是第一次出现该字符,并且要建立pattern[i]到arr[i]的映射关系。但在建立映射关系之前,需要检查mp2是否已经包含了arr[i](也就是当前的单词)。如果mp2已经包含了当前的单词,说明该单词已经被映射到其他的字符上,违反了唯一映射的规则,直接返回false。 - 如果
mp已经包含了pattern[i],则检查pattern[i]对应的值是否等于arr[i]。如果不等于,说明当前的模式字符已经被映射到了其他的单词上,违反了一一对应的规则,直接返回false。 - 剩下的就是将
mp2中建立单词到字符的反向映射关系,即将arr[i]映射到pattern[i]
// 最终可以得到:
// 示例 :pattern = "abba", s = "dog cat cat dog"
// mp: Map { 'a' => 'dog', 'b' => 'cat' } , mp2: Map { 'dog' => 'a', 'cat' => 'b' }
三、代码答案
/**
* @param {string} pattern
* @param {string} s
* @return {boolean}
*/
var wordPattern = function (pattern, s) {
const arr = s.split(' ')
if (pattern.length !== arr.length) return false;
const mp = new Map();
const mp2 = new Map();
for (let i = 0; i < pattern.length; i++) {
if (!mp.has(pattern[i])) {
if (mp2.has(arr[i])) return false;
mp.set(pattern[i], arr[i])
}
if (mp.get(pattern[i]) !== arr[i]) return false;
mp2.set(arr[i], pattern[i])
}
return true;
};