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

LeetCode 418 - 屏幕可显示句子的数量

在这里插入图片描述
在这里插入图片描述

文章目录

    • 摘要
    • 描述
    • 题解答案
    • 题解代码分析
    • 示例测试及结果
    • 时间复杂度
    • 空间复杂度
    • 总结

摘要

今天我们来聊一道挺有意思的题目 —— LeetCode 418《屏幕可显示句子的数量(Sentence Screen Fitting)》。这道题乍一看像是字符串模拟题,但如果你一股脑儿暴力模拟,性能会很糟糕。想要高效求解,就得找到循环规律,而不是一格格地去填屏幕。下面我会用 Swift 实现完整的解法,并结合一个实际场景来说明这类问题在“文本排版引擎”或“信息显示屏系统”中的应用。

描述

题目要求是这样的:

我们有一个由若干单词组成的句子,比如 ["hello", "world"]。屏幕有固定的行数 rows 和列数 cols。每行从左到右显示句子内容,单词之间用一个空格隔开。
要求计算:整个句子可以在屏幕上完整地显示多少次。

需要注意:

  • 单词不能被拆开跨行。
  • 每次从句子的第一个单词重新开始。
  • 屏幕装不下一个完整单词就要换行。

举个例子:

sentence = ["hello", "world"]
rows = 2
cols = 8

第一行能显示 "hello"(5个字符)+空格(1)=6个位置,剩下2个空位不够放 "world",所以换行。
第二行能显示 "world"(5个字符),剩下3个空位,不够继续放 "hello"
这时正好显示了整个句子一次,因此答案是 1

题解答案

最直观的思路是:一行行模拟,把每个单词往里塞,但这样复杂度是 O(rows × avg_word_length),对于大输入非常慢。
所以我们换一种方式——字符串拼接 + 模拟滑动

思路如下:

  1. 把句子拼接成一个带空格的长字符串,比如 s = "hello world "

  2. 维护一个指针 pos 表示我们在整个字符串中的当前位置。

  3. 对每一行:

    • pos += cols(表示当前行能放下这么多字符)
    • 如果 s[pos % len] 是空格,就说明刚好到单词边界,pos++
    • 如果不是空格,说明中间断了一个单词,需要回退到单词起始位置(向左走直到遇到空格)
  4. 最后,整个句子在屏幕上完整显示的次数为 pos / len

这个算法其实相当于把所有行“拼”成一个大字符串,通过位置计算得到循环次数。

题解代码分析

我们用 Swift 实现这个思路,代码如下:

import Foundationclass Solution {func wordsTyping(_ sentence: [String], _ rows: Int, _ cols: Int) -> Int {// 将句子拼成一个带空格的长字符串let s = sentence.joined(separator: " ") + " "let n = s.countvar pos = 0  // 当前在字符串中的位置for _ in 0..<rows {pos += cols  // 当前行放下这么多字符// 如果正好落在空格上,跳过空格if s[s.index(s.startIndex, offsetBy: pos % n)] == " " {pos += 1} else {// 向左回退直到找到空格while pos > 0 && s[s.index(s.startIndex, offsetBy: (pos - 1) % n)] != " " {pos -= 1}}}// pos / n 就是完整句子在屏幕上显示的次数return pos / n}
}// 可运行 Demo
let solution = Solution()
let result = solution.wordsTyping(["hello", "world"], 2, 8)
print("可显示完整句子的次数是:\(result)")

代码解析

  1. sentence.joined(separator: " ") + " ":拼接句子形成循环字符串,方便处理边界。
  2. pos 累加每行的列数,模拟光标往后走。
  3. 判断当前落点是不是空格,如果不是,就往回走,保证不会拆单词。
  4. 最终除以句子长度,就是能完整显示多少次。

这种思路之所以高效,是因为每行的扫描都是基于字符长度,而不是单词遍历,相当于用一个滑动窗口在循环字符串上移动。

示例测试及结果

示例1:

let result1 = solution.wordsTyping(["hello", "world"], 2, 8)
print(result1) // 输出 1

示例2:

let result2 = solution.wordsTyping(["a", "bcd", "e"], 3, 6)
print(result2) // 输出 2

解释:
屏幕宽 6,高 3:

第1行: a bcd
第2行: e a
第3行: bcd e

完整显示了 2 次句子。

示例3:

let result3 = solution.wordsTyping(["I", "had", "apple", "pie"], 4, 5)
print(result3) // 输出 1

时间复杂度

每一行我们最多往回移动若干字符,但整体最多扫描字符串的长度上限。
因此时间复杂度是:

O(rows)

因为 pos 只向前移动(或小范围回退),不会超过 rows * cols

空间复杂度

除了拼接字符串和几个变量外,没有额外结构,空间复杂度为:

O(1)

总结

这道题核心在于:不要一行一行地暴力塞,而是把句子看作一个循环字符串,用一个移动的指针去模拟“打印”过程。
这种技巧在实际场景中非常常见,比如:

  • 移动设备的文本滚动显示:小屏幕上反复显示一句宣传语。
  • LED 信息屏或跑马灯系统:同一串文字不断循环显示。
  • 电子阅读器分页引擎:根据屏幕尺寸动态计算能显示多少内容。
http://www.dtcms.com/a/581829.html

相关文章:

  • 每日两题day36
  • LLM(大语言模型)
  • Solidity 与 x402 协议
  • 逆变器之SPWM调制
  • Java基础——常用算法5
  • Qt数据可视化实战:饼图、线图与表格的完整指南
  • qq代挂网站建设ps怎么做网站的广告条
  • 两个显示器鼠标方向调整
  • window server2008下Oracle 配置dblink查询 MySQL 数据
  • 软件数据库测试:【数据库质量保障:从单元测试到性能优化】
  • Windows安装Mujoco
  • vue3切换路由时页面空白问题解决办法
  • 时尚网站设计案例网站建设与网站主机的选择
  • 只买域名不建网站手机网站页面模板
  • Via安卓纯净版浏览器 v6.7.1去广解锁高级版
  • Ubuntu 24编译Android源码问题解决
  • 南宁市建设工程质量安全协会网站男性专科正规医院
  • 企业为什么建设网站wordpress5无法创建目录
  • Flutter 加固方案对比与实战,多工具组合的跨平台安全体系(Flutter App 加固/IPA 成品混淆/Ipa Guard CLI/自动化安全流程)
  • Qt/QML DelegateModel基础用法示例
  • 使用hping3进行网络协议测试与防火墙测试的完整指南
  • 西安网站建设市场烟台网站建设团队
  • 如何使用指标来确定趋势
  • 【vsftpd】centos和ubuntu部署vsftpd服务
  • 各大网站发布seo点击
  • Apache Jena SPARQL 查询完全指南:入门与实战案例
  • 做电影网站成本响应式网站开发asp
  • 中文网站开发语言wordpress广告模板下载地址
  • Elimination英文单词学习
  • S31-WinCC单个窗口多次调用