当前位置: 首页 > news >正文

【LeetCode 每日一题】1935. 可以输入的最大单词数

Problem: 1935. 可以输入的最大单词数

文章目录

  • 整体思路
  • 完整代码
  • 时空复杂度
    • 时间复杂度:O(N + M)
    • 空间复杂度:O(N + M)

整体思路

这段代码的目的是计算在一个给定的文本 text 中,有多少个单词是可以被完整打出的。判断的标准是,这个单词不包含任何 brokenLetters 字符串中指定的“损坏”的字母。

该算法采用了一种清晰、分步的策略:分割 -> 预处理 -> 逐词检查

  1. 第一步:分割文本为单词

    • String[] words = text.split(" ");:算法首先将输入的 text 字符串按照空格进行分割,得到一个包含所有单词的字符串数组 words
  2. 第二步:预处理损坏的字母

    • 为了能够快速地判断一个字母是否是“损坏”的,算法将 brokenLetters 字符串中的所有字符存入一个 哈希集合 (HashSet) broken
    • 目的HashSet 提供了平均时间复杂度为 O(1)contains() 查找操作,这远比在 brokenLetters 字符串中进行线性搜索要高效得多。
  3. 第三步:逐词检查并计数

    • 算法采用了一种“减法”的计数策略。
    • 初始化int ans = words.length;,首先假设所有单词都可以被打出。
    • 遍历:然后,通过一个 for-each 循环,遍历 words 数组中的每一个 word
    • 逐字检查:对于每个 word,再进入一个内层循环,遍历该单词的每一个字符 c
    • 判断与中断
      • if (broken.contains(c)): 使用预处理好的 broken 集合,快速检查当前字符 c 是否是损坏的。
      • 如果 c 是损坏的,那么整个 word 就无法被打出。此时,将计数器 ans 减一 (ans--)。
      • break;: 一旦发现一个损坏的字母,就没有必要再检查这个单词的其余字母了。break 语句会立即跳出内层循环,开始检查下一个单词,这是一个有效的优化。
    • 如果一个单词的所有字符都被检查完而没有触发 break,那么 ans 的值就不会因这个单词而改变,它仍然被算作一个可以打出的单词。
  4. 返回结果

    • 在检查完所有单词后,ans 中存储的就是最终可以被打出的单词的总数。

完整代码

import java.util.HashSet;
import java.util.Set;class Solution {/*** 计算文本中有多少个单词可以被完整打出。* @param text          输入的文本字符串* @param brokenLetters 包含所有损坏字母的字符串* @return 可以被打出的单词数量*/public int canBeTypedWords(String text, String brokenLetters) {// 步骤 1: 将文本按空格分割成单词数组String[] words = text.split(" ");// 步骤 2: 预处理损坏的字母,存入 HashSet 以便快速查找Set<Character> broken = new HashSet<>();for (char c : brokenLetters.toCharArray()) {broken.add(c);}// 步骤 3: 初始化计数器为总单词数,然后减去无法打出的单词int ans = words.length;// 遍历每一个单词for (String word : words) {// 遍历当前单词的每一个字符for (char c : word.toCharArray()) {// 使用 HashSet 进行 O(1) 的快速检查if (broken.contains(c)) {// 如果单词中包含任何一个损坏的字母,则该单词无法打出ans--; // 将计数器减一break; // 无需再检查此单词的其余字母,跳出内层循环}}}return ans;}
}

时空复杂度

  • Ntext 的总长度。
  • MbrokenLetters 的长度。
  • Wtext 中的单词数。
  • L 为最长单词的长度。

时间复杂度:O(N + M)

  1. 分割字符串text.split(" ") 的时间复杂度与文本长度 N 成正比,即 O(N)
  2. 构建 broken 集合:遍历 brokenLetters 并将其字符加入 HashSet。时间复杂度为 O(M)
  3. 检查单词
    • 外层循环遍历 W 个单词。
    • 内层循环遍历每个单词的字符。
    • word.toCharArray() 的时间与单词长度成正比。
    • broken.contains(c) 是 O(1) 操作。
    • 所有内层循环的总执行次数,等于 text 中所有非空格字符的总数。这个总数小于等于 N
    • 因此,整个检查过程的时间复杂度与 text 的总长度 N 成正比,即 O(N)

综合分析
总的时间复杂度是 O(N) + O(M) + O(N) = O(2N + M)。简化后,可以表示为 O(N + M)

空间复杂度:O(N + M)

  1. words 数组text.split(" ") 会创建一个新的字符串数组。在最坏的情况下(例如,每个字符都是一个单词,用空格隔开),这个数组可能需要存储大约 N/2 个字符串对象。总的空间占用与 text 的长度 N 相关,为 O(N)
  2. broken 集合HashSet 需要存储 brokenLetters 中的所有唯一字符。其空间复杂度为 O(M)
  3. toCharArray() 副本:在循环中,word.toCharArray() 会为每个单词创建一个临时的字符数组副本。由于这个空间是可复用的,所以它只影响峰值内存使用,其大小为 O(L)(最长单词长度)。

综合分析
算法所需的额外空间主要由 words 数组和 broken 集合决定。因此,总的空间复杂度为 O(N + M)

http://www.dtcms.com/a/391546.html

相关文章:

  • eeprom和flash的区别
  • [vibe code追踪] 分支图可视化 | SVG画布 | D3.js
  • [硬件电路-264]:数字电路的电源系统的主要特性包括哪些
  • 算法题(212):01背包(空间优化)
  • TP4054和TP4056对比
  • AD5165(超低功耗逻辑电平数字电位器)芯片的详细用法
  • 38、多模态模型基础实现:视觉与语言的智能融合
  • 租赁合同管理系统如何使用?功能深度解析
  • 构建高质量RAG知识库,文档解析破解AI应用的数据质量难题
  • CS课程项目设计17:基于Face_Recognition人脸识别库的课堂签到系统
  • 跨平台开发地图:客户端技术选型指南 | 2025年9月
  • 隐私保护 vs 技术创新:AI 时代数据安全的边界在哪里?
  • 如何在网页开发中建立数字信任?
  • 网站模版 网站建站 网站设计源码模板
  • 访问飞牛NAS的时候为啥要加:5667?不能隐藏它吗?啥是重定向?HTTPS为啥是红的?
  • 端口切换导致 mcp 和 gimini cli 连接失败
  • (论文速读)KL-CLIP:零采样异常分割的K均值学习模型
  • FlexE实践笔记
  • 搭建Redis群集模式
  • 视觉SLAM第13讲:实践,设计SLAM系统
  • 【论文阅读】WebWalker: Benchmarking LLMs in Web Traversal
  • 页面水印记录
  • 快速学习kotlin并上手 Android 开发指南
  • Linux进程控制(下):进程等待和进程替换
  • 如何检查数据库是否处于恢复模式
  • AI一周资讯 250913-250919
  • Livox-mid-360录制的.lvx2文件转化为.bag文件(TBC)
  • 【 svn】自动重试: cleanup + update
  • 有哪些Java学习书籍推荐?
  • 机动车登记证 OCR 识别:让车辆业务办理驶入 “快车道“