问题
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.
例子
words: ["This", "is", "an", "example", "of", "text", "justification."]
L: 16.
Return the formatted lines as:
[
"This is an",
"example of text",
"justification. "
]
分析
遍历输入的字符串数组,维护一个字符计数器,每遍历一个字符串更新计数器。当计数器的值加上下一个字符串的长度大于L时,把以前遍历过的字符串排列成一行,用空格填充空白部分。要注意以下四点:
- 当空格不能被平分时,左边的空白优先分配到更多的空格;
- 当一行有多个字符串时,中间对齐;
- 当一行只有一个字符串时,左对齐;
- 最后一行左对齐;
要点
- 要考虑各种边界情况
- 把重用的功能抽象成函数
时间复杂度
O(n),n是输入字符串数组的大小
空间复杂度
O(1)
代码
class Solution {
public:
vector<string> fullJustify(vector<string>& words, int maxWidth) {
vector<string> res, line;
int cnt = 0;
for (int i = 0; i < words.size(); i++) {
if (cnt + words[i].size() + line.size() > maxWidth) {
res.push_back(padding(line, cnt, maxWidth));
line.clear();
cnt = 0;
}
line.push_back(words[i]);
cnt += words[i].size();
}
string lastLineStr(line[0]);
for (int i = 1; i < line.size(); i++)
lastLineStr += ' ' + line[i];
lastLineStr += string(maxWidth - lastLineStr.size(), ' ');
res.push_back(lastLineStr);
return res;
}
private:
string padding(const vector<string> &line, int cnt, int maxWidth) {
if (line.size() == 1)
return line[0] + string(maxWidth - line[0].size(), ' ');
string lineStr;
int spaceNum = maxWidth - cnt;
int spaceCnt = line.size() - 1;
for (int j = 0; j < line.size() - 1; j++) {
int spaceSpan = j == line.size() - 2 ? spaceNum : ceil((float)spaceNum / spaceCnt);
lineStr += line[j] + string(spaceSpan, ' ');
spaceNum -= spaceSpan;
spaceCnt--;
}
lineStr += line.back();
return lineStr;
}
};