68. 文本左右对齐
1. 题目
给定一个单词数组 words
和一个长度 maxWidth
,重新排版单词,使其成为每行恰好有 maxWidth
个字符,且左右两端对齐的文本。
你应该使用 “贪心算法” 来放置给定的单词;也就是说,尽可能多地往每行中放置单词。必要时可用空格 ' '
填充,使得每行恰好有 maxWidth 个字符。
要求尽可能均匀分配单词间的空格数量。如果某一行单词间的空格不能均匀分配,则左侧放置的空格数要多于右侧的空格数。
文本的最后一行应为左对齐,且单词之间不插入额外的空格。
注意:
- 单词是指由非空格字符组成的字符序列。
- 每个单词的长度大于 0,小于等于 maxWidth。
- 输入单词数组
words
至少包含一个单词。
示例 1:
1 | 输入: words = ["This", "is", "an", "example", "of", "text", "justification."], maxWidth = 16 |
示例 2:
1 | 输入:words = ["What","must","be","acknowledgment","shall","be"], maxWidth = 16 |
示例 3:
1 | 输入:words = ["Science","is","what","we","understand","well","enough","to","explain","to","a","computer.","Art","is","everything","else","we","do"],maxWidth = 20 |
提示:
1 <= words.length <= 300
1 <= words[i].length <= 20
words[i]
由小写英文字母和符号组成1 <= maxWidth <= 100
words[i].length <= maxWidth
2. 思路
已知题目关键规则为以下:
- [1] 尽可能在每一行中放置多的单词
- [2] 单词A与单词B之间至少存在1个空格
- [3] 文本的最后一行应当是左对齐,最后一行单词之间不存在额外的空格
- [4] 应当尽可能地分配单词之间的空格数量,如果一行单词之间的空格不能平均分配,则左侧放置的空格数要多于右侧的空格数
- [5] 每个单词的长度大于 0,小于等于 maxWidth
初始化下标,遍历
words
数组,逐位移动下标,将满足maxWidth
范围内的字符串下标进行记录确定要写入行的单词下标后,初始化
perSpace
变量用于记录每个单词后要跟的空格数量,同时判断即将写入该行的单词数量:- 如果写入该行的单词数量为1,则单词后要跟的空格数量
perSpace
值为maxWidth - 写入单词的长度
- 如果写入该行的单词数量大于1,则单词后要跟的空格数量
perSpace
值为(maxWidth - 写入单词的长度) / (单词数量 - 1)
,计算得到平均分配的空格数量,其中单词数量 - 1
是值2个单词中只需要1个空格占位
- 如果写入该行的单词数量为1,则单词后要跟的空格数量
继续计算
additionalSpace
,即是平均分配完空格后,多余的需要再次分配的空格- 如果写入该行的单词数量为1,则需要额外分配空格的值为0
- 如果写入该行的单词数量大于1,则需要额外分配空格的值为
maxWidth - (perSpace * (单词数量 - 1) + 写入单词的长度)
在正式写入前,初始化变量
lastLine
,用于判断要写入的单词下标中是否包含了words
数组的最后一位遍历上述提到的需要写入该行的单词下标,初始化
str
变量用于追加单词,并在完成遍历后,将该行写入结果集result
中,在遍历过程中,需要判断:- 当写入的单词数量为1时,则直接追加余下所有空格
- 当写入的单词不是该行的最后一个单词时,每个单词后都需要追加
perSpace
个空格 - 当前行不是最后一行,同时
additionalSpace
值仍然大于0时,为了满足规则[3]和规则[4],追加1个空格字符进str
变量中,同时对additionalSpace
进行减一,通过此操作达到平均分配,因为该数量为余数,肯定无法再完整分配完一轮,因此可以直接采用追加1个单位的空格字符 - 当前行时最后一行,且已是最后一个单词时,则对该单词后进行剩余所有空白字符的填充,满足规则[3]左对齐
3. 代码
1 | class Solution { |
4. 复杂度
- 时间复杂度:
O(n)
- 空间复杂度:
O(n)