【LeetCode】290. 单词规律
解题思路
题目要求判断字符串 s 中的单词是否与模式 pattern 中的字符形成 双向唯一映射,即每个字符对应唯一的单词,且每个单词也仅对应唯一字符。核心要点如下:
- 双向哈希表映射:用两个哈希表分别记录字符到单词、单词到字符的映射关系。
- 长度匹配检查:分割后的单词数量必须与模式长度相同。
- 冲突检测:遍历字符与单词时,若发现已有映射冲突,立即返回
false。
Golang 实现代码
import "strings" func wordPattern(pattern string, s string) bool { words := strings.Split(s, " ") // 长度不匹配直接返回false if len(pattern) != len(words) { return false } charToWord := make(map[byte]string) // 字符到单词的映射 wordToChar := make(map[string]byte) // 单词到字符的映射 for i := 0; i < len(pattern); i++ { char := pattern[i] word := words[i] // 检查字符→单词的映射冲突 if mappedWord, exists := charToWord[char]; exists { if mappedWord != word { return false } } else { // 检查单词→字符的映射冲突 if mappedChar, exists := wordToChar[word]; exists { if mappedChar != char { return false } } // 更新双向映射 charToWord[char] = word wordToChar[word] = char } } return true }
关键逻辑说明
-
字符串分割与长度检查(第4-7行):
strings.Split将字符串s按空格分割为单词列表。- 若分割后的单词数量与模式长度不同,直接返回
false。
-
双向哈希表维护(第9-25行):
- 字符→单词检查:若字符已映射但对应的单词与当前单词不符,返回
false。 - 单词→字符检查:若单词已映射但对应的字符与当前字符不符,返回
false。 - 新增映射:当双向映射均未记录时,更新两个哈希表。
- 字符→单词检查:若字符已映射但对应的单词与当前单词不符,返回
示例验证
- 示例1(
pattern="abba", s="dog cat cat dog"):a→dog,b→cat,双向映射一致,返回true。
- 示例2(
pattern="abba", s="dog cat cat fish"):- 最后一个单词
fish无法映射到a,返回false。
- 最后一个单词
- 示例3(
pattern="aaaa", s="dog cat cat dog"):a需同时映射到多个不同单词,违反唯一性,返回false。
- 极端情况(
pattern="abba", s="dog dog dog dog"):b尝试映射已绑定a的单词dog,冲突返回false。
复杂度分析
| 维度 | 说明 |
|---|---|
| 时间复杂度 | O(n),遍历字符和单词一次完成检查。 |
| 空间复杂度 | O(n),哈希表存储所有唯一映射关系。 |
扩展优化
- 数组替代哈希表:若字符仅限小写字母(ASCII 97-122),可用长度为26的数组优化空间。
- 索引比较法:通过比较字符和单词首次出现的位置是否一致,但需注意时间复杂度可能因多次遍历上升。

浙公网安备 33010602011771号