【LeetCode】290. 单词规律

leetcode

 

解题思路

题目要求判断字符串 s 中的单词是否与模式 pattern 中的字符形成 ​双向唯一映射,即每个字符对应唯一的单词,且每个单词也仅对应唯一字符。核心要点如下:

  1. 双向哈希表映射:用两个哈希表分别记录字符到单词、单词到字符的映射关系。
  2. 长度匹配检查:分割后的单词数量必须与模式长度相同。
  3. 冲突检测:遍历字符与单词时,若发现已有映射冲突,立即返回 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
}

 


关键逻辑说明

  1. 字符串分割与长度检查​(第4-7行):

    • strings.Split 将字符串 s 按空格分割为单词列表。
    • 若分割后的单词数量与模式长度不同,直接返回 false。
  2. 双向哈希表维护​(第9-25行):

    • 字符→单词检查:若字符已映射但对应的单词与当前单词不符,返回 false
    • 单词→字符检查:若单词已映射但对应的字符与当前字符不符,返回 false
    • 新增映射:当双向映射均未记录时,更新两个哈希表。

示例验证

  1. 示例1​(pattern="abba", s="dog cat cat dog"):
    • a→dogb→cat,双向映射一致,返回 true。
  2. 示例2​(pattern="abba", s="dog cat cat fish"):
    • 最后一个单词 fish 无法映射到 a,返回 false。
  3. 示例3​(pattern="aaaa", s="dog cat cat dog"):
    • a 需同时映射到多个不同单词,违反唯一性,返回 false。
  4. 极端情况​(pattern="abba", s="dog dog dog dog"):
    • b 尝试映射已绑定 a 的单词 dog,冲突返回 false。

复杂度分析

维度说明
时间复杂度 O(n),遍历字符和单词一次完成检查。
空间复杂度 O(n),哈希表存储所有唯一映射关系。

扩展优化

  • 数组替代哈希表:若字符仅限小写字母(ASCII 97-122),可用长度为26的数组优化空间。
  • 索引比较法:通过比较字符和单词首次出现的位置是否一致,但需注意时间复杂度可能因多次遍历上升。
posted @ 2025-03-19 20:44  云隙之间  阅读(27)  评论(0)    收藏  举报