Leetcode力扣秋招刷题路-0068
从0开始的秋招刷题路,记录下所刷每道题的题解,帮助自己回顾总结
68. 文本左右对齐
给定一个单词数组 words 和一个长度 maxWidth ,重新排版单词,使其成为每行恰好有 maxWidth 个字符,且左右两端对齐的文本。
你应该使用 “贪心算法” 来放置给定的单词;也就是说,尽可能多地往每行中放置单词。必要时可用空格 ’ ’ 填充,使得每行恰好有 maxWidth 个字符。
要求尽可能均匀分配单词间的空格数量。如果某一行单词间的空格不能均匀分配,则左侧放置的空格数要多于右侧的空格数。
文本的最后一行应为左对齐,且单词之间不插入额外的空格。
注意:
单词是指由非空格字符组成的字符序列。
每个单词的长度大于 0,小于等于 maxWidth。
输入单词数组 words 至少包含一个单词。
示例 1:
输入: words = [“This”, “is”, “an”, “example”, “of”, “text”, “justification.”], maxWidth = 16
输出:
[
“This is an”,
“example of text”,
"justification. "
]
示例 2:
输入:words = [“What”,“must”,“be”,“acknowledgment”,“shall”,“be”], maxWidth = 16
输出:
[
“What must be”,
"acknowledgment ",
"shall be "
]
解释: 注意最后一行的格式应为 "shall be " 而不是 “shall be”,
因为最后一行应为左对齐,而不是左右两端对齐。
第二行同样为左对齐,这是因为这行只包含一个单词。
示例 3:
输入:words = [“Science”,“is”,“what”,“we”,“understand”,“well”,“enough”,“to”,“explain”,“to”,“a”,“computer.”,“Art”,“is”,“everything”,“else”,“we”,“do”],maxWidth = 20
输出:
[
“Science is what we”,
“understand well”,
“enough to explain to”,
“a computer. Art is”,
“everything else we”,
"do "
]
提示:
1 <= words.length <= 300
1 <= words[i].length <= 20
words[i] 由小写英文字母和符号组成
1 <= maxWidth <= 100
words[i].length <= maxWidth
一个句子,和一个长度表示一行最长的长度,然后对齐文本,有下边几个规则。
- 同一个单词只能出现在一行中,不能拆分
- 一行如果只能放下一个单词,该单词放在最左边,然后空格补齐,例如 “acknowledgement#####”,这里只是我为了直观,# 表示空格,题目并没有要求。
- 一行如果有多个单词,最左边和最右边不能有空格,每个单词间隙尽量平均,如果无法平均,把剩余的空隙从左边开始分配。例如,“enough###to###explain##to”,3 个间隙,每个 2 个空格的话,剩下 2 个空格,从左边依次添加一个空格。
- 最后一行执行左对齐,单词间一个空格,末尾用空格补齐。
解法一
这道题关键就是理解题目,然后就是一些细节的把控了,我主要是下边的想法。
一行一行计算该行可以放多少个单词,然后计算单词间的空隙是多少,然后把它添加到结果中。
public List<String> fullJustify(String[] words, int maxWidth) {List<String> ans = new ArrayList<>();//当前行单词已经占用的长度int currentLen = 0;//保存当前行的单词List<String> row = new ArrayList<>();//遍历每个单词for (int i = 0; i < words.length;) {//判断加入该单词是否超过最长长度//分了两种情况,一种情况是加入第一个单词,不需要多加 1//已经有单词的话,再加入单词,需要多加个空格,所以多加了 1if (currentLen == 0 && currentLen + words[i].length() <= maxWidth|| currentLen > 0 && currentLen + 1 + words[i].length() <= maxWidth) {row.add(words[i]);if (currentLen == 0) {currentLen = currentLen + words[i].length();} else {currentLen = currentLen + 1 + words[i].length();}i++;//超过的最长长度,对 row 里边的单词进行处理} else {//计算有多少剩余,也就是总共的空格数,因为之前计算 currentLen 多算了一个空格,这里加回来int sub = maxWidth - currentLen + row.size() - 1;//如果只有一个单词,那么就直接单词加空格就可以if (row.size() == 1) {String blank = getStringBlank(sub);ans.add(row.get(0) + blank);} else {//用来保存当前行的结果StringBuilder temp = new StringBuilder();//将第一个单词加进来temp.append(row.get(0));//计算平均空格数int averageBlank = sub / (row.size() - 1);//如果除不尽,计算剩余空格数int missing = sub - averageBlank * (row.size() - 1);//前 missing 的空格数比平均空格数多 1String blank = getStringBlank(averageBlank + 1);int k = 1;for (int j = 0; j < missing; j++) {temp.append(blank + row.get(k));k++;}//剩下的空格数就是求得的平均空格数blank = getStringBlank(averageBlank);for (; k < row.size(); k++) {temp.append(blank + row.get(k));}//将当前结果加入 ans.add(temp.toString());}//清空以及置零row = new ArrayList<>();currentLen = 0;}}//单独考虑最后一行,左对齐StringBuilder temp = new StringBuilder();temp.append(row.get(0));for (int i = 1; i < row.size(); i++) {temp.append(" " + row.get(i));}//剩余部分用空格补齐temp.append(getStringBlank(maxWidth - currentLen));//最后一行加入到结果中ans.add(temp.toString());return ans;
}
//得到 n 个空白
private String getStringBlank(int n) {StringBuilder str = new StringBuilder();for (int i = 0; i < n; i++) {str.append(" ");}return str.toString();
}
但是这个算法,在 leetcode 跑,速度只打败了 30% 多的人,1 ms。然后在 discuss 里转了一圈寻求原因,发现大家思路都是这样子,然后找了一个人的跑了下
public List<String> fullJustify(String[] words, int maxWidth) {int left = 0; List<String> result = new ArrayList<>();while (left < words.length) {int right = findRight(left, words, maxWidth);result.add(justify(left, right, words, maxWidth));left = right + 1;}return result;
}//找到当前行最右边的单词下标
private int findRight(int left, String[] words, int maxWidth) {int right = left;int sum = words[right++].length();while (right < words.length && (sum + 1 + words[right].length()) <= maxWidth)sum += 1 + words[right++].length();return right - 1;
}//根据不同的情况添加不同的空格
private String justify(int left, int right, String[] words, int maxWidth) {if (right - left == 0) return padResult(words[left], maxWidth);boolean isLastLine = right == words.length - 1;int numSpaces = right - left;int totalSpace = maxWidth - wordsLength(left, right, words);String space = isLastLine ? " " : blank(totalSpace / numSpaces);int remainder = isLastLine ? 0 : totalSpace % numSpaces;StringBuilder result = new StringBuilder();for (int i = left; i <= right; i++)result.append(words[i]).append(space).append(remainder-- > 0 ? " " : "");return padResult(result.toString().trim(), maxWidth);
}//当前单词的长度
private int wordsLength(int left, int right, String[] words) {int wordsLength = 0;for (int i = left; i <= right; i++) wordsLength += words[i].length();return wordsLength;
}private String padResult(String result, int maxWidth) {return result + blank(maxWidth - result.length());
}private String blank(int length) {return new String(new char[length]).replace('\0', ' ');
}
看了下,发现思想和自己也是一样的。但是这个速度却打败了 100% ,0 ms。考虑了下,差别应该在我的算法里使用了一个叫做 row 的 list 用来保存当前行的单词,用了很多 row.get ( index ),而上边的算法只记录了 left 和 right 下标,取单词直接用的 words 数组。然后尝试着在我之前的算法上改了一下,去掉 row,用两个变量 start 和 end 保存当前行的单词范围。主要是 ( end - start ) 代替了之前的 row.size ( ), words [ start + k ] 代替了之前的 row.get ( k )。
public List<String> fullJustify2(String[] words, int maxWidth) {List<String> ans = new ArrayList<>();int currentLen = 0;int start = 0;int end = 0;for (int i = 0; i < words.length;) {//判断加入该单词是否超过最长长度//分了两种情况,一种情况是加入第一个单词,不需要多加 1//已经有单词的话,再加入单词,需要多加个空格,所以多加了 1if (currentLen == 0 && currentLen + words[i].length() <= maxWidth|| currentLen > 0 && currentLen + 1 + words[i].length() <= maxWidth) {end++;if (currentLen == 0) {currentLen = currentLen + words[i].length();} else {currentLen = currentLen + 1 + words[i].length();}i++;} else {int sub = maxWidth - currentLen + (end - start) - 1;if (end - start == 1) {String blank = getStringBlank(sub);ans.add(words[start] + blank);} else {StringBuilder temp = new StringBuilder();temp.append(words[start]);int averageBlank = sub / ((end - start) - 1);//如果除不尽,计算剩余空格数int missing = sub - averageBlank * ((end - start) - 1);String blank = getStringBlank(averageBlank + 1);int k = 1;for (int j = 0; j < missing; j++) {temp.append(blank + words[start+k]);k++;}blank = getStringBlank(averageBlank);for (; k <(end - start); k++) {temp.append(blank + words[start+k]);}ans.add(temp.toString());}start = end;currentLen = 0;}}StringBuilder temp = new StringBuilder();temp.append(words[start]);for (int i = 1; i < (end - start); i++) {temp.append(" " + words[start+i]);}temp.append(getStringBlank(maxWidth - currentLen));ans.add(temp.toString());return ans;
}
//得到 n 个空白
private String getStringBlank(int n) {StringBuilder str = new StringBuilder();for (int i = 0; i < n; i++) {str.append(" ");}return str.toString();
}
果然,速度也到了打败 100%,0 ms。
总
充分说明 list 的读取还是没有数组的直接读取快呀,还有就是要向上边的作者学习,多封装几个函数,思路会更加清晰,代码也会简明。
相关文章:
Leetcode力扣秋招刷题路-0068
从0开始的秋招刷题路,记录下所刷每道题的题解,帮助自己回顾总结 68. 文本左右对齐 给定一个单词数组 words 和一个长度 maxWidth ,重新排版单词,使其成为每行恰好有 maxWidth 个字符,且左右两端对齐的文本。 你应该…...
Nginx介绍及安装(windows版,Linux版)
目录 一、Nginx介绍 1、Nginx优势 2、Nginx作用 3、部署静态资源 4、代理 5、负载均衡 二、Nginx安装步骤(windows版) 三、Nginx安装步骤(Linux版) 1、官网下载安装包,下载完之后上传到Linux系统上 2、在Lin…...
Camera | 4.瑞芯微平台MIPI摄像头应用程序编写
前面3篇我们讲解了camera的基础概念,MIPI协议,CSI2,常用命令等,本文带领大家入门,如何用c语言编写应用程序来操作摄像头。 Linux下摄像头驱动都是基于v4l2架构,要基于该架构编写摄像头的应用程序ÿ…...
【1250. 检查「好数组」】
来源:力扣(LeetCode) 描述: 给你一个正整数数组 nums,你需要从中任选一些子集,然后将子集中每一个数乘以一个 任意整数,并求出他们的和。 假如该和结果为 1,那么原数组就是一个「…...
Spring 如何解决循环依赖?
什么是循环依赖 ? 一个或多个对象之间存在直接或间接的依赖关系,这种依赖关系构成一个环形调用,有下面 3 种方式。 我们看一个简单的 Demo,对标“情况 2”。 Service public class Louzai1 {Autowiredprivate Louzai2 louzai2;…...
CocoaPods使用指南
前言 对于大多数软件开发团队来说,依赖管理工具必不可少,它能针对开源和私有依赖进行安装与管理,从而提升开发效率,降低维护成本。针对不同的语言与平台,其依赖管理工具也各有不同,例如 npm 管理 Javascri…...
Kafka 消息队列
目录主流的消息队列消息队列的应用场景缓存/肖锋解耦异步处理KafkaKafka的定义Kafka的底层基础架构Kafka分区如何保证Leader选举Kafka分区如何保证Leader和Follower数据的一致性Kafka 中消费者的消费方式Kafka 高效读写数据的原因(高性能吞吐的原因)&…...
华为OD机试 - 挑选字符串(Python)| 真题+思路+考点+代码+岗位
挑选字符串 题目 给定a-z,26 个英文字母小写字符串组成的字符串A和B, 其中A可能存在重复字母,B不会存在重复字母, 现从字符串A中按规则挑选一些字母可以组成字符串B 挑选规则如下: 同一个位置的字母只能挑选一次, 被挑选字母的相对先后顺序不能被改变, 求最多可以同时…...
对比Hashtable、HashMap、TreeMap有什么不同?
第9讲 | 对比Hashtable、HashMap、TreeMap有什么不同? Map 是广义 Java 集合框架中的另外一部分,HashMap 作为框架中使用频率最高的类型之一,它本身以及相关类型自然也是面试考察的热点。 今天我要问你的问题是,对比 Hashtable、…...
测试新版Android Studio的手机镜像效果
学更好的别人, 做更好的自己。 ——《微卡智享》 本文长度为669字,预计阅读2分钟 前言 春节刚上班,就开始了疯狂出差的节奏,期间发现Android Studio发布新的版本2022.1.1(Electric Eel),里面两个更新的内容蓝牙模拟器和…...
女生可以参加IT培训吗?
2023年了,就不要把性别当作选择专业的前提条件了。虽然这句话说过很多次了,作为IT行业来说,是非常欢迎女生的加入;尤其是整天都是面对一大堆男攻城狮,工作氛围一点都不活跃,反而显得压抑和杂乱,…...
刷题25-重排链表
重排链表 解题思路:通过观察链表可以发现,把链表一分为二,后半段链表反转,然后两个链表穿插连接,当链表的节点总数是奇数时,要保证链表的前半段比后半段多一个节点。 关于把链表一分为二,可以…...
VHDL-延迟模型-惯性延迟与传输延迟
目录 1,惯性延时 2,传输延时 信号通过元件都会有延迟,延迟时间的计算是逻辑仿真的重要功能。考虑延迟信息得到的仿真输出波形可以更精确地反映实际电路的情况。针对元件的延时,人们根据需要建立了一些用的延时模型,这…...
2023年美赛(MCM/ICM)简介
2023年美赛将要如期开赛,这里为了 让大家对今年的美赛有一个直接 客观的了解。对2023年美赛(MCM/ICM)进行一下简要的介绍。相关资料大家可以查看另一篇文章一、竞赛时间February 16-20, 2023开赛时间 北京时间 17号(本周五) 6:00结束时间 北京时间 21号(…...
5min完成linux环境Jenkins的安装
5min搞定linux环境Jenkins的安装安装Jenkinsstep1: 使用wget 命令下载Jenkinsstep2、创建Jenkins日志目录并运行jekinsstep3、访问jenkins并解锁jenkins,安装插件以及创建管理员用户step4、到此,就完成了Finish、以上步骤中遇到的问题1、 jenkins启动不了…...
华为OD机试 - 字母计数(Python)| 真题+思路+考点+代码+岗位
字母计数 题目 给出一个只包含字母的字符串, 不包含空格,统计字符串中各个子字母(区分大小写)出现的次数, 并按照字母出现次数从大到小的顺序输出各个字母及其出现次数 如果次数相同,按照自然顺序排序,且小写字母在大写字母之前 输入 输入一行仅包含字母的字符串 输出 按…...
DENSE 数据集 - STF 数据集(CVPR 2020)
DENSE 数据集 - STF 数据集 - Seeing Through Fog Without Seeing Fog: Deep Multimodal Sensor Fusion in Unseen Adverse Weather(CVPR 2020)摘要1. 引言2. 相关工作3. 多模式恶劣天气数据集3.1 多模态传感器设置3.2 记录4. 自适应深度融合4.1 自适应多…...
华为OD机试 - 静态扫描最优成本(Python)| 真题+思路+考点+代码+岗位
静态扫描最优成本 题目 静态扫描快速识别源代码的缺陷,静态扫描的结果以扫描报告作为输出: 文件扫描的成本和文件大小相关,如果文件大小为 N ,则扫描成本为 N 个金币扫描报告的缓存成本和文件大小无关,每缓存一个报告需要 M 个金币扫描报告缓存后,后继再碰到该文件则不…...
【ns-3】零基础安装教程
文章目录前言1. 安装虚拟机及Ubuntu2. 安装依赖库3. 下载ns-34. 构建ns-3前言 近期因工作需要开始接触ns-3。作者零基础,从零开始顺利完成了ns-3的安装。本篇为ns-3安装过程记录贴或针对小白的零基础教程。 本篇内容所使用到的软件版本信息如下:VMware…...
华为OD机试 - 新学校选址(Python)| 真题+思路+考点+代码+岗位
新学校选址 题目 为了解新学期学生暴涨的问题,小乐村要建立所新学校 考虑到学生上学安全问题,需要所有学生家到学校的距离最短. 假设学校和所有学生家都走在一条直线之上,请问学校建立在什么位置, 能使得到学校到各个学生家的距离和最短 输入 第一行: 整数 n 取值范围 [1,1…...
零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?
一、核心优势:专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发,是一款收费低廉但功能全面的Windows NAS工具,主打“无学习成本部署” 。与其他NAS软件相比,其优势在于: 无需硬件改造:将任意W…...
【Linux】shell脚本忽略错误继续执行
在 shell 脚本中,可以使用 set -e 命令来设置脚本在遇到错误时退出执行。如果你希望脚本忽略错误并继续执行,可以在脚本开头添加 set e 命令来取消该设置。 举例1 #!/bin/bash# 取消 set -e 的设置 set e# 执行命令,并忽略错误 rm somefile…...
对WWDC 2025 Keynote 内容的预测
借助我们以往对苹果公司发展路径的深入研究经验,以及大语言模型的分析能力,我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际,我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测,聊作存档。等到明…...
linux 错误码总结
1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...
python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)
更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...
【JavaWeb】Docker项目部署
引言 之前学习了Linux操作系统的常见命令,在Linux上安装软件,以及如何在Linux上部署一个单体项目,大多数同学都会有相同的感受,那就是麻烦。 核心体现在三点: 命令太多了,记不住 软件安装包名字复杂&…...
【开发技术】.Net使用FFmpeg视频特定帧上绘制内容
目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法,当前调用一个医疗行业的AI识别算法后返回…...
今日学习:Spring线程池|并发修改异常|链路丢失|登录续期|VIP过期策略|数值类缓存
文章目录 优雅版线程池ThreadPoolTaskExecutor和ThreadPoolTaskExecutor的装饰器并发修改异常并发修改异常简介实现机制设计原因及意义 使用线程池造成的链路丢失问题线程池导致的链路丢失问题发生原因 常见解决方法更好的解决方法设计精妙之处 登录续期登录续期常见实现方式特…...
大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计
随着大语言模型(LLM)参数规模的增长,推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长,而KV缓存的内存消耗可能高达数十GB(例如Llama2-7B处理100K token时需50GB内存&a…...
初学 pytest 记录
安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...
