LeetCode每日一题,20250914

元音拼写检查器

思路

  1. 精确匹配

    • HashSet 保存原始单词,查询时直接判断是否存在。
  2. 大小写忽略匹配

    • HashMap<String, String> 保存 小写单词 -> 第一次出现的原始单词
    • putIfAbsent,确保只记录第一次出现的单词。
  3. 元音模糊匹配

    • 把单词里所有元音替换为 *,得到模糊形式。
    • HashMap<String, String> 保存 模糊形式 -> 第一次出现的原始单词
    • 查询时同样先转小写再模糊化,然后查表。

查询优先级

  • 精确匹配 → 大小写匹配 → 元音模糊匹配 → 否则返回 ""
java 复制代码
class Solution {

    String vowels = "aeiou";

    public String[] spellchecker(String[] wordlist, String[] queries) {
        Set<String> wordSet = new HashSet<>();             // 精确匹配
        Map<String, String> caseMap = new HashMap<>();     // 忽略大小写
        Map<String, String> vowelMap = new HashMap<>();    // 忽略元音

        // 预处理 wordlist
        for (String word : wordlist) {
            wordSet.add(word);

            String lower = word.toLowerCase();
            caseMap.putIfAbsent(lower, word);

            String devoweled = devowel(lower);
            vowelMap.putIfAbsent(devoweled, word);
        }

        String[] ans = new String[queries.length];

        // 查询
        for (int i = 0; i < queries.length; i++) {
            String query = queries[i];

            if (wordSet.contains(query)) {  // 精确匹配
                ans[i] = query;
            } else {
                String lower = query.toLowerCase();

                if (caseMap.containsKey(lower)) {  // 大小写匹配
                    ans[i] = caseMap.get(lower);
                } else {
                    String devoweled = devowel(lower);
                    ans[i] = vowelMap.getOrDefault(devoweled, "");
                }
            }
        }

        return ans;
    }

    // 把所有元音替换成 '*'
    private String devowel(String word) {
        StringBuilder sb = new StringBuilder();
        for (char c : word.toCharArray()) {
            if (vowels.indexOf(c) != -1) {
                sb.append('*');
            } else {
                sb.append(c);
            }
        }
        return sb.toString();
    }
}

方法二,用stream流

明白了,我帮你重整理,把 devowel 函数相关的语法(3,4,5)归为一个类,同时去掉 6,7。这样笔记更清晰、针对性更强。


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

class Solution {
    private final String vowels = "aeiou";

    public String[] spellchecker(String[] wordlist, String[] queries) {
        // 精确匹配
        Set<String> wordSet = new HashSet<>(Arrays.asList(wordlist));

        // 大小写忽略,保存第一次出现的原始单词
        Map<String, String> caseMap = Arrays.stream(wordlist)
                .collect(Collectors.toMap(
                        w -> w.toLowerCase(),
                        w -> w,
                        (oldVal, newVal) -> oldVal   // 保证第一次出现
                ));

        // 元音忽略,保存第一次出现的原始单词
        Map<String, String> vowelMap = Arrays.stream(wordlist)
                .collect(Collectors.toMap(
                        w -> devowel(w.toLowerCase()),
                        w -> w,
                        (oldVal, newVal) -> oldVal   // 保证第一次出现
                ));

        // 查询处理(用 stream 映射)
        return Arrays.stream(queries)
                .map(q -> {
                    if (wordSet.contains(q)) {
                        return q; // 精确匹配
                    }
                    String lower = q.toLowerCase();
                    if (caseMap.containsKey(lower)) {
                        return caseMap.get(lower); // 忽略大小写
                    }
                    return vowelMap.getOrDefault(devowel(lower), ""); // 忽略元音
                })
                .toArray(String[]::new);
    }

    // 把元音替换成 *
    private String devowel(String word) {
        return word.chars()
                .mapToObj(c -> vowels.indexOf(c) != -1 ? "*" : String.valueOf((char) c))
                .collect(Collectors.joining());
    }
}

代码解析

1️⃣ 数组和 List 的区别

java 复制代码
Set<String> wordSet = new HashSet<>(Arrays.asList(wordlist));
  • wordlist数组 (String[])
  • HashSet 构造函数需要 Collection 类型(List/Set 等),数组本身不是 Collection
  • Arrays.asList(wordlist) → 把数组转成 List,方便初始化 Set
特性 数组 (String[]) List (List<String>)
大小 固定 可变
方法 .length add, remove, contains 等
接口 不实现 Collection 实现 Collection
可作为构造参数 不可以 可以

2️⃣ Stream + Collectors.toMap(构建 Map)

java 复制代码
Map<String, String> caseMap = Arrays.stream(wordlist)
    .collect(Collectors.toMap(
        w -> w.toLowerCase(),      // key 映射规则
        w -> w,                    // value 映射规则
        (oldVal, newVal) -> oldVal // key 冲突时保留第一次出现
    ));
  • Arrays.stream(wordlist) → 把数组转成 Stream
  • Collectors.toMap(keyMapper, valueMapper, mergeFunction)
参数 作用
keyMapper Stream 元素如何生成 key (w -> w.toLowerCase())
valueMapper Stream 元素如何生成 value (w -> w)
mergeFunction key 冲突时如何处理 (oldVal, newVal) -> oldVal → 保留第一次出现

示例

java 复制代码
wordlist = {"KiTe", "kite", "Hare"}
Map -> {"kite" -> "KiTe", "hare" -> "Hare"}
  • 保证第一次出现的单词被记录,不被后续重复覆盖

3️⃣ devowel 函数解析(字符流 + 拼接)

java 复制代码
private String devowel(String word) {
    return word.chars()
            .mapToObj(c -> vowels.indexOf(c) != -1 ? "*" : String.valueOf((char) c))
            .collect(Collectors.joining());
}
3.1 word.chars()
  • 将字符串拆成 IntStream
  • 每个字符是 Unicode 编码的 int
  • 示例:
java 复制代码
"Hi".chars() -> 72, 105
3.2 String.valueOf((char) c)
  • chars() 返回的是 int
  • (char) c → 把 int 转回字符
  • String.valueOf(char) → 把字符变成长度为 1 的字符串
  • 用于最终拼接
3.3 Collectors.joining()
  • 将 Stream 中的每个字符串 拼接成一个完整字符串
  • 内部使用 StringBuilder,不会像 s += c 那样每次循环都生成新对象
  • 高效拼接字符串

总结 devowel 技巧

  1. word.chars() → 拆成字符流
  2. (char) c + String.valueOf() → 字符转换成字符串
  3. Collectors.joining() → 高效拼接
相关推荐
王哈哈^_^1 分钟前
【数据集】【YOLO】【目标检测】农作物病害数据集 11498 张,病害检测,YOLOv8农作物病虫害识别系统实战训推教程。
人工智能·深度学习·算法·yolo·目标检测·计算机视觉·1024程序员节
xier_ran3 分钟前
邻接矩阵的 k 次幂意味着什么?从图论到路径计数的直观解释
算法·图论
B站_计算机毕业设计之家1 小时前
预测算法:股票数据分析预测系统 股票预测 股价预测 Arima预测算法(时间序列预测算法) Flask 框架 大数据(源码)✅
python·算法·机器学习·数据分析·flask·股票·预测
007php0072 小时前
京东面试题解析:同步方法、线程池、Spring、Dubbo、消息队列、Redis等
开发语言·后端·百度·面试·职场和发展·架构·1024程序员节
想唱rap2 小时前
C++ list 类的使用
c语言·开发语言·数据结构·c++·笔记·算法·list
l1t2 小时前
利用DuckDB SQL求解集合数学题
数据库·sql·算法·集合·duckdb
yuyanjingtao2 小时前
CCF-GESP 等级考试 2024年9月认证C++四级真题解析
c++·算法·青少年编程·gesp·csp-j/s
微笑尅乐2 小时前
洗牌算法讲解——力扣384.打乱数组
算法·leetcode·职场和发展
Lei_3359672 小时前
[算法]背包DP(01背包、完全背包问题、多重背包、分组背包、混合背包问题、有依赖的背包问题等)
c++·算法
uesowys2 小时前
华为OD算法开发指导-比赛的冠亚季军
算法·华为od