【简单】力扣算法题解析LeetCode290:单词规律

关注文末推广名片,即可免费获得本题测试源码

题目来源:LeetCode290:单词规律

问题抽象: 给定一个字符模式 pattern(仅小写字母)和一个单词字符串 s(单词间由空格分隔),要求判断 s 中的单词序列是否与 pattern 中的字符序列满足 双射映射关系,满足以下核心需求:

  1. 映射规则定义

    • 双射性
      • pattern 的每个字符必须 唯一映射s 的一个单词(单射性);
      • s 的每个单词必须 唯一映射pattern 的一个字符(满射性);
    • 顺序一致性s 的第 i 个单词必须映射到 pattern 的第 i 个字符(0 ≤ i < len(pattern))。
  2. 输入约束

    • pattern 长度 1 ≤ len(pattern) ≤ 300s 长度 1 ≤ len(s) ≤ 3000
    • 单词仅由小写字母组成,空格分隔(无前导/尾随空格);
    • 时间复杂度 O(n)(单次遍历字符串)。
  3. 边界处理

    • 长度不等:若 s 的单词数 ≠ len(pattern),直接返回 false
    • 全相同模式:如 pattern="aaa"s="cat cat cat"truea→"cat");
    • 字符单词数冲突:如 pattern="aa"s="cat dog"falsea 需同时映射 "cat""dog");
    • 单词字符冲突:如 pattern="ab"s="dog dog"false"dog" 映射 ab)。
  4. 特殊案例

    • 空模式或空字符串:题目保证非空输入;
    • 单字符模式:pattern="a"s="apple"truea→"apple");
    • 重复单词:pattern="aba"s="cat dog cat"truea→"cat", b→"dog")。

输入:字符串 pattern, 字符串 s
输出:布尔值(是否满足双射映射)。


解题思路

  1. 双向映射验证

    • 需要确保 pattern 中的每个字符与 s 中的单词是一一对应的,即:
      • 同一个字符不能映射到不同的单词。
      • 不同的字符不能映射到同一个单词。
  2. 核心步骤

    • 分割字符串:将 s 按空格分割成单词数组。
    • 长度校验:若 pattern 长度与单词数组长度不相等,直接返回 false
    • 双映射维护
      • 使用 charToWord 存储字符到单词的映射。
      • 使用 wordToChar 存储单词到字符的映射。
    • 遍历校验
      • 若字符已在 charToWord 中,检查当前单词是否匹配映射值。
      • 若字符未出现,但单词已存在于 wordToChar 中,说明其他字符已映射该单词,返回 false
      • 若均为新映射,则添加字符↔单词的双向映射。
  3. 亮点: 提前长度校验避免无效遍历。双哈希表实现 O(1) 时间复杂度的映射检查。


代码实现(Java版)🔥点击下载源码

class Solution {
    public boolean wordPattern(String pattern, String s) {
        // 分割字符串s为单词数组
        String[] words = s.split(" ");
        // 长度不等直接返回false
        if (pattern.length() != words.length) {
            return false;
        }
        
        // 字符到单词的映射
        Map<Character, String> charToWord = new HashMap<>();
        // 单词到字符的映射
        Map<String, Character> wordToChar = new HashMap<>();
        
        // 遍历pattern和单词数组
        for (int i = 0; i < pattern.length(); i++) {
            char ch = pattern.charAt(i);
            String word = words[i];
            
            // 检查字符映射是否一致
            if (charToWord.containsKey(ch)) {
                // 已映射的单词与当前单词不匹配
                if (!charToWord.get(ch).equals(word)) {
                    return false;
                }
            } else {
                // 单词已被其他字符映射
                if (wordToChar.containsKey(word)) {
                    return false;
                }
                // 添加双向映射
                charToWord.put(ch, word);
                wordToChar.put(word, ch);
            }
        }
        return true;
    }
}

代码说明

  1. 分割字符串s.split(" ") 按空格分割字符串为单词数组。
  2. 长度校验:若 pattern.length() != words.length,直接返回 false,确保一一对应。
  3. 双映射维护
    • charToWord:记录字符(Key)到单词(Value)的映射。
    • wordToChar:记录单词(Key)到字符(Value)的映射。
  4. 遍历校验
    • 若字符 ch 已存在映射,检查当前单词是否匹配映射值(charToWord.get(ch).equals(word))。
    • 若字符 ch 未出现,但单词 word 已被其他字符映射(wordToChar.containsKey(word)),返回 false
    • 若均为新映射,则添加双向映射(charToWord.put(ch, word)wordToChar.put(word, ch))。
  5. 复杂度:时间复杂度 O(n),空间复杂度 O(n),其中 n 为 pattern 的长度。

提交详情(执行用时、内存消耗)

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

达文汐

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值