题目来源:🔒LeetCode288:单词的唯一缩写
问题抽象: 设计一个类 ValidWordAbbr,用于高效验证给定单词在字典中的缩写是否唯一(即字典中不存在其他单词具有相同缩写),满足以下核心需求:
-
缩写规则定义:
- 短单词(长度
≤2):缩写为原单词(如"a"→"a"); - 长单词(长度
≥3):缩写为首字母 + (长度-2) + 尾字母(如"hello"→"h3o")。
- 短单词(长度
-
类功能定义:
- 初始化:接收字符串数组
dictionary(字典),构建缩写映射; - 唯一性验证:
isUnique(word)判断word的缩写在字典中是否 仅由该单词独占(无其他单词共享)。
- 初始化:接收字符串数组
-
唯一性规则:
- 独占条件:若字典中存在与
word相同缩写的单词,则这些单词必须 全是word本身(允许重复); - 无冲突:若字典中无任何单词与
word缩写相同,视为唯一; - 存在冲突:若字典中存在 不同于
word的单词 与其缩写相同,视为不唯一。
- 独占条件:若字典中存在与
-
输入约束:
- 字典长度
1 ≤ len(dictionary) ≤ 3×10^4,单词长度1 ≤ len(word) ≤ 50; - 时间复杂度:
- 初始化 O(n)(
n为字典单词总数); isUnique方法 O(1)(哈希表查询);
- 初始化 O(n)(
- 空间复杂度 O(n)(存储缩写映射)。
- 字典长度
-
边界处理:
- 空字典:初始化无单词,所有
isUnique查询返回true; - 重复单词:如字典
["a","a"],isUnique("a")返回true(独占缩写); - 缩写相同但单词不同:如字典
["deer","door"],isUnique("dear")返回false(缩写均为"d2r"); - 单词不在字典:如字典
["cake"],isUnique("cane")返回false(缩写"c2e"冲突)。
- 空字典:初始化无单词,所有
类接口定义:
class ValidWordAbbr {
public ValidWordAbbr(String[] dictionary); // 初始化
public boolean isUnique(String word); // 验证唯一性
}
解题思路
-
核心问题:
- 判断目标单词的缩写是否仅由自身使用(若它在字典中),或未被任何字典单词使用(若它不在字典中)。
-
优化策略:
- 哈希表存储缩写计数:预处理字典,计算每个单词的缩写并记录出现次数。
- 去重处理:字典可能有重复单词,需用
Set存储原始单词,避免重复计数。 - 边界处理:单词长度≤2时无需计算缩写,直接返回
true。
-
关键逻辑(
isUnique方法):- 若目标单词的缩写不存在于字典 → 唯一(
true)。 - 若目标单词在字典中,且其缩写仅由它自己使用(计数=1) → 唯一(
true)。 - 其他情况(缩写被其他单词使用) → 不唯一(
false)。
- 若目标单词的缩写不存在于字典 → 唯一(
代码实现(Java版)🔥点击下载源码
public class ValidWordAbbr {
private final Map<String, Integer> abbrCountMap; // 存储缩写及其出现次数
private final Set<String> wordSet; // 存储字典原始单词(去重)
public ValidWordAbbr(String[] dictionary) {
abbrCountMap = new HashMap<>();
wordSet = new HashSet<>(Arrays.asList(dictionary)); // 去重
for (String word : wordSet) {
String abbr = getAbbreviation(word);
// 仅处理长度>2的单词(长度≤2的缩写即自身,无需存储)
if (abbr != null) {
abbrCountMap.put(abbr, abbrCountMap.getOrDefault(abbr, 0) + 1);
}
}
}
public boolean isUnique(String word) {
// 长度≤2的单词缩写即自身,默认唯一
if (word.length() <= 2) {
return true;
}
String abbr = getAbbreviation(word);
// 情况1:缩写不存在于字典 → 唯一
if (!abbrCountMap.containsKey(abbr)) {
return true;
}
// 情况2:单词在字典中且其缩写仅被自己使用 → 唯一
if (wordSet.contains(word) && abbrCountMap.get(abbr) == 1) {
return true;
}
// 其他情况:缩写被其他单词占用 → 不唯一
return false;
}
// 辅助方法:生成单词缩写(长度>2时)
private String getAbbreviation(String word) {
if (word.length() <= 2) {
return null; // 长度≤2的单词无需生成特殊缩写
}
return word.charAt(0) +
String.valueOf(word.length() - 2) +
word.charAt(word.length() - 1);
}
}
代码说明
-
预处理字典:
wordSet去重存储字典单词,避免重复计数(如["a","a"]视为一个单词)。abbrCountMap仅存储长度>2单词的缩写,减少内存占用。
-
缩写生成逻辑:
- 长度≤2的单词(如
"it")在isUnique中直接判断为唯一,不生成缩写。 - 长度>2的单词缩写格式:
首字母 + (长度-2) + 尾字母(如"dog"→"d1g")。
- 长度≤2的单词(如
-
唯一性判断:
- 目标单词的缩写未出现在
abbrCountMap中 → 唯一(true)。 - 目标单词在字典中且其缩写计数为1 → 唯一(
true)。 - 缩写被其他单词占用 → 不唯一(
false)。
- 目标单词的缩写未出现在
-
复杂度。 时间复杂度:构造方法:
O(N),N为字典去重后的单词数。isUnique:O(1)(哈希表查询)。空间复杂度:O(N)(存储缩写和单词集合)。

975

被折叠的 条评论
为什么被折叠?



