leetcode68. Text Justification
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了leetcode68. Text Justification相关的知识,希望对你有一定的参考价值。
Given an array of words and a length L, format the text such that each line has exactly L characters and is fully (left and right) justified.
You should pack your words in a greedy approach; that is, pack as many words as you can in each line. Pad extra spaces ‘ ‘
when necessary so that each line has exactly L characters.
Extra spaces between words should be distributed as evenly as possible. If the number of spaces on a line do not divide evenly between words, the empty slots on the left will be assigned more spaces than the slots on the right.
For the last line of text, it should be left justified and no extra space is inserted between words.
For example,
words: ["This", "is", "an", "example", "of", "text", "justification."]
L: 16
.
Return the formatted lines as:
[ "This is an", "example of text", "justification. " ]
问题如上,此题要求把给定的一组单词合理划分成几行,使每一行都有尽可能多的单词,并且使单词与单词之间的空字符合理分布,且此行字符长度不得超过给定长度。
这道题的总体思路很简单,然而具体实现却又很复杂。
先说一下大体思路。首先是每一行的单词选择,每一行都由一个或多个单词和空字符组成,且单词必须按原始顺序排列,所以只要不断累加单词和空字符的长度,当累加长度大于给定长度时,则说明最后加入的这个单词不能放入这一行,因此这一行就由最后一个单词前面的单词所组成,同样下一行再通过这样的方式去判断,就可以得出每一行应选择的单词。
因此判断每行所选择的单词就涉及到了两个条件,一是单词的长度,单词的长度可以通过size函数获取;二是每行空字符的数量,根据题意,单词与单词之间至少有一个空字符,因此判断 当前累加单词长度+单词数量-1>给定长度 即可,然后在这个条件判断内部获取前面的单词和进行空字符分配。
然而,通过上面的方式并不能得到最后一行的单词,最后一行的单词累加长度+必须的空字符数量<=给定长度,所以上面那种方法并不适用于最后一行的单词选择。这里可以通过判断 给定的这一组单词剩余的单词长度+必须的空字符数量<=给定长度 来选择最后一行的单词,这种方式肯定会增加程序的复杂程度。
另一种方式很简单,只需要给给定数组push进一个和给定长度相当的任意字符串即可,这样在选择最后一行的单词时时,就可以符合上面的条件。
words.push_back(string(maxWidth, ‘a‘));
在确定好当前行应选择的单词后,就应该将单词push进新数组,同时分配空字符。
空字符的分配相比较每行单词的选择更为复杂,首先需要知道每行空字符的数量,因为每行字符长度不得超过给定长度,因此 当前行空字符数量=给定长度-当前行单词累加长度,
然后需要知道每行应分配几处空字符,即空字符应分配的区域有几处,通过例子可以看出,当单词数量为1时,有一处空字符,且空字符在最右边,当单词数量大于1时,空字符数量均匀分布,当不能完全均匀分布时,左边的空字符数量要多于右边,因此:
k-- > 0 ? 当前位置应分配的空字符数量 = 当前行空字符数量 / 空字符应分配的区域数量 + 1 : 当前位置应分配的空字符数量 = 当前行空字符数量 / 空字符应分配的区域数量; str += string(当前位置应分配的空字符数量, ‘ ‘);
这里的k=当前行空字符数量%空字符应分配的区域数量。
上面的第一行代码就可以实现空字符的均匀分配,然后通过第二行代码将与该行当前区域应分配的空字符数量相当的空字符写入str中。
需要注意的是,最后一行并不是按照这个规则来进行空字符分配的。因此,最后一行的空字符需要另外分配。
下面是代码,已在leetcode通过测试。
class Solution { public: vector<string> fullJustify(vector<string> &words, int maxWidth) { vector<string> sum; //用于返回处理完后的数组 int wordsWidth = 0; int nullCharTotalWidth, nullCharArea, nullCharWidth; //每行空字符总数量,每行空字符区间,每个空字符区间中空字符的数量 int start = 0; int k; string str = ""; int flag = 0; words.push_back(string(maxWidth, ‘a‘)); for (int i = 0; i < words.size(); ++i) { wordsWidth += words[i].size(); nullCharArea = i - start; if (wordsWidth + nullCharArea > maxWidth) { --nullCharArea == 0 ? nullCharArea = 1 : nullCharArea = nullCharArea; nullCharTotalWidth = maxWidth - wordsWidth + words[i].size(); k = nullCharTotalWidth % nullCharArea; for (int j = start; j < i; ++j) { str += words[j]; if (i == words.size() - 1) { if (j < i - 1) { str += " "; flag++; } else str += string(nullCharTotalWidth - flag, ‘ ‘); continue; } if ((j == i - 1) && (start != i - 1)) break; k-- > 0 ? nullCharWidth = nullCharTotalWidth / nullCharArea + 1 : nullCharWidth = nullCharTotalWidth / nullCharArea; str += string(nullCharWidth, ‘ ‘); } sum.push_back(str); if (i == words.size() - 1) break; str = ""; wordsWidth = 0; start = i--; } } return sum; } };
ps.本来用了另一种方式实现,且代码行数更少,但与testcase不符,感觉有点为了结果而制造结果,以后不会这样了。。。
以上是关于leetcode68. Text Justification的主要内容,如果未能解决你的问题,请参考以下文章
leetcode 68 Text Justification ----- java
[leetcode]68. Text Justification文字对齐
LeetCode -- 68.Text Justification
LeetCode 68: Text Justification