目录
一、问题分析
二、解题思路
三、代码实现
四、复杂度分析
五、总结
在编程的世界里,我们常常会遇到各种有趣的字符串匹配问题。今天要探讨的就是这样一个问题:给定一种规律 pattern 和一个字符串 s,判断 s 是否遵循与 pattern 相同的规律。这里的 “遵循” 意味着 pattern 里的每个字母和字符串 s 中的每个非空单词之间存在着双向连接的对应规律。
一、问题分析
首先,我们明确一下问题的关键要求:
pattern仅包含小写英文字母,其长度范围是1 <= pattern.length <= 300。s包含小写英文字母和空格,且不包含前导或尾随空格,每个单词由单个空格分隔,长度范围是1 <= s.length <= 3000。pattern与s之间的对应关系必须是双向的,即一个字母对应一个特定单词,且一个单词也只能对应一个特定字母。
二、解题思路
为了判断这种双向对应关系,我们可以利用两个哈希表来分别记录从 pattern 中的字符到 s 中的单词的映射,以及从 s 中的单词到 pattern 中的字符的映射。
- 首先,将字符串
s按照空格进行分割,得到一个单词数组ss。如果pattern的长度与ss的长度不相等,那么直接返回false,因为它们不可能存在一一对应的关系。 - 然后,遍历
pattern和ss,对于每一个位置i:- 将
pattern中的字符作为键,ss中的单词作为值存入map哈希表。 - 将
ss中的单词作为键,pattern中的字符作为值存入map1哈希表。
- 将
- 最后,再次遍历
pattern和ss,检查map和map1中的映射关系是否正确。如果在任何位置发现不匹配的情况,即map中通过字符获取的单词与实际的ss[i]不相等,或者map1中通过单词获取的字符与实际的pattern.charAt(i)不相等,就返回false。如果整个遍历过程都没有发现不匹配,那么说明s遵循pattern的规律,返回true。
过题图片

三、代码实现
以下是使用 Java 实现的代码:
class Solution {
public boolean wordPattern(String pattern, String s) {
// 用于存储从 pattern 中的字符到 s 中的单词的映射
HashMap<Character,String> map = new HashMap<>();
// 用于存储从 s 中的单词到 pattern 中的字符的映射
HashMap<String,Character> map1 = new HashMap<>();
// 将 s 按照空格分割成单词数组
String[] ss = s.split(" ");
// 如果 pattern 长度与单词数组长度不相等,直接返回 false
if(pattern.length()!= ss.length) return false;
// 遍历 pattern 和单词数组,建立双向映射
for(int i = 0; i < pattern.length(); i++){
map.put(pattern.charAt(i), ss[i]);
map1.put(ss[i], pattern.charAt(i));
}
// 再次遍历,检查映射关系是否正确
for(int i = 0; i < pattern.length(); i++){
if(!map.get(pattern.charAt(i)).equals(ss[i])){
return false;
}
if(!map1.get(ss[i]).equals(pattern.charAt(i))){
return false;
}
}
return true;
}
}
四、复杂度分析
- 时间复杂度:主要的操作是对
pattern和ss进行两次遍历。第一次遍历用于建立哈希表,时间复杂度为 ,其中 是pattern的长度(也是ss的长度)。第二次遍历用于检查映射关系,时间复杂度也为 。所以总的时间复杂度为 。 - 空间复杂度:需要创建两个哈希表来存储映射关系,在最坏情况下,哈希表中可能存储
pattern中的所有字符和ss中的所有单词,所以空间复杂度为 ,其中 是pattern的长度(也是ss的长度)。
题目链接
290. 单词规律 - 力扣(LeetCode)
五、总结
题目要求判断字符串 s 与给定的规律 pattern 是否完全匹配,这里的匹配是一种双向连接的对应关系,即 pattern 里的每个字母要和 s 中的每个非空单词一一对应,且反之亦然。同时,题目对 pattern 和 s 的长度、字符组成以及 s 的单词分隔形式等都做了相应限定,明确这些要求是正确解题的基础。



















