编程-技术-算法-leetcode-288. 单词的唯一缩写

你需要实现一个 ValidWordAbbr 类,核心是预处理字典生成"缩写-单词集合"的映射 ,从而高效判断目标单词的缩写是否唯一。相比每次遍历字典的暴力解法,预处理能将 isUnique 方法的时间复杂度优化到接近 O(1)(仅生成缩写的时间与单词长度相关),更符合工程最佳实践。

解题思路

  1. 预处理字典
    • 构造函数接收字典后,遍历所有单词,为每个单词生成缩写;
    • HashMap<String, Set<String>> 存储映射关系:key 是缩写,value 是该缩写对应的所有不同单词的集合 (用 Set 去重,避免字典中重复单词干扰判断)。
  2. 唯一性判断逻辑
    • 生成目标单词的缩写;
    • 若字典中无该缩写 → 唯一(返回 true);
    • 若字典中有该缩写,检查对应的单词集合:
      • 若集合中只有当前单词本身 → 唯一(返回 true);
      • 否则 → 不唯一(返回 false)。

完整Java代码

java 复制代码
import java.util.*;

public class ValidWordAbbr {
    // 核心映射:缩写 -> 对应的所有不同单词集合
    private final Map<String, Set<String>> abbrToWords;

    // 构造函数:初始化字典的缩写映射
    public ValidWordAbbr(String[] dictionary) {
        abbrToWords = new HashMap<>();
        for (String word : dictionary) {
            String abbr = getAbbreviation(word);
            // 若缩写不存在,初始化空集合;否则复用已有集合
            abbrToWords.computeIfAbsent(abbr, k -> new HashSet<>()).add(word);
        }
    }

    // 辅助方法:生成单词的缩写(严格遵循题目规则)
    private String getAbbreviation(String word) {
        int len = word.length();
        // 长度 ≤ 2,缩写为单词本身
        if (len <= 2) {
            return word;
        }
        // 长度 > 2:首字母 + 中间字母数 + 尾字母
        return word.charAt(0) + String.valueOf(len - 2) + word.charAt(len - 1);
    }

    // 核心方法:判断单词的缩写是否唯一
    public boolean isUnique(String word) {
        String targetAbbr = getAbbreviation(word);
        // 情况1:字典中无该缩写 → 唯一
        if (!abbrToWords.containsKey(targetAbbr)) {
            return true;
        }
        // 情况2:字典中有该缩写,检查所有对应单词是否都是当前单词
        Set<String> words = abbrToWords.get(targetAbbr);
        // 集合大小为1 且 唯一元素等于当前word → 唯一
        return words.size() == 1 && words.contains(word);
    }

    // 测试用例(匹配题目示例)
    public static void main(String[] args) {
        String[] dictionary = {"deer", "door", "cake", "card"};
        ValidWordAbbr validWordAbbr = new ValidWordAbbr(dictionary);
        
        System.out.println(validWordAbbr.isUnique("dear"));  // false(d2r对应{deer,door})
        System.out.println(validWordAbbr.isUnique("cart"));  // true(c2t无对应)
        System.out.println(validWordAbbr.isUnique("cane"));  // false(c2e对应{cake}≠cane)
        System.out.println(validWordAbbr.isUnique("make"));  // true(m2e无对应)
        
        // 边界测试:字典中有重复单词
        String[] dict2 = {"a", "a"};
        ValidWordAbbr v2 = new ValidWordAbbr(dict2);
        System.out.println(v2.isUnique("a"));  // true(a对应{a})
        
        // 边界测试:字典为空
        ValidWordAbbr v3 = new ValidWordAbbr(new String[]{});
        System.out.println(v3.isUnique("test"));  // true
    }
}

代码关键部分解释

  1. 映射结构 abbrToWords
    • HashMap 存储缩写与单词集合的映射,预处理一次字典即可复用,避免每次 isUnique 遍历字典;
    • Set 存储单词,自动去重(比如字典中有多个 "a",仅存一个,不影响判断)。
  2. 缩写生成方法 getAbbreviation
    • 严格遵循题目规则:长度 ≤ 2 直接返回单词,长度 > 2 拼接首字母、中间长度、尾字母。
  3. isUnique 核心逻辑
    • 先判断缩写是否存在,不存在则直接唯一;
    • 若存在,仅当"缩写对应的单词集合只有当前单词"时,才满足唯一条件(符合题目中"所有缩写相同的单词都与word相同"的规则)。

复杂度分析

  • 初始化(构造函数) :O(n * L),n 是字典单词数,L 是单词平均长度(生成缩写的时间);
  • isUnique 方法 :O(L),仅需生成目标单词的缩写(L 是目标单词长度),后续哈希表和集合操作都是 O(1)。

总结

  1. 核心优化点:预处理字典生成缩写-单词集合映射 ,避免重复遍历字典,提升多次调用 isUnique 的效率;
  2. 唯一性判断的关键:要么缩写不存在,要么缩写对应的所有单词都是当前单词;
  3. 边界处理:兼容空字典、重复单词、短单词(长度≤2)等场景,保证逻辑正确性。
相关推荐
逆境不可逃4 小时前
【LeetCode 912】排序数组——随机化快速排序详解
数据结构·算法·排序算法
Coder-magician4 小时前
《代码随想录》刷题打卡day31:动态规划-背包问题part02
算法·动态规划
薛定e的猫咪4 小时前
从因果视角解决多智能体协作:细读 SCIC 算法
算法
Forever Nore4 小时前
LeetCode 14 最长公共前缀 - 纵向扫描
linux·服务器·leetcode
c238564 小时前
《算法武林谱:四大排序神功与二分寻宝术全解》
数据结构·算法·排序算法
圣保罗的大教堂4 小时前
leetcode 3090. 每个字符最多出现两次的最长子字符串 简单
leetcode
格林威4 小时前
多相机并行采图最佳实践:Task.WhenAll + 异常处理 + 资源释放
开发语言·人工智能·数码相机·计算机视觉·c#·视觉检测·机器视觉
一米阳光86614 小时前
软考(中级)软件设计师核心笔记(9)算法——时间复杂度与空间复杂度、查找算法、排序算法
笔记·算法·职场发展·软考·软件设计师·中级职称
Mem0rin4 小时前
二分查找:左右边界
数据结构·算法
yuhulkjv33512 小时前
Claude表格复制到word不再崩溃,AI导出鸭批量导出+格式无损一键搞定
人工智能·ai·c#·word·ai导出鸭