根据题解:
大体思路是判断几个单词放在一行中,即这几个单词加上其后面固定的空格的长度小于maxWidth
。
满足条件后,进入fillWords
函数中进行字符串的处理。
其中,要注意最后一行的处理(左对齐)。
处理过程如下:(其实就是空格的处理)
- 计算单词数量
wordCount
- 计算减去固定空格数量和单词长度的空格数量
spaceCount
- 对于每个单词(除了最后一个单词),其后面一定有一个固定空格,然后就是平分剩下空格spaceCount。
- 平分的过程:
- 平均每个单词空隙分配
spaceCount / (wordCount - 1)
个空格 - 多出来的空格(假设是
spaceExtra
)分配给前spaceExtra
个空隙
- 对于只有一个单词 / 最后一行 两种情况的讨论
- 最后一行的每个单词只有后面的固定空格,即
spaceSuffix
- 不进行剩余空格的平分过程
- 最后一行的每个单词只有后面的固定空格,即
class Solution {
public:
string fillWords(vector<string>& words, int bg, int ed, int maxWidth, bool lastLine = false) {
int wordCount = ed - bg + 1;
int spaceCount = maxWidth + 1 - wordCount; // +1相当于抵消最后一个单词后面的空格
for (int i = bg; i <= ed; ++i) {
spaceCount -= words[i].size();
}
int spaceSuffix = 1;
// 如果一行只有一个单词不用平分空格
int spaceAvg = (wordCount == 1) ? 0 : spaceCount / (wordCount - 1);
int spaceExtra = (wordCount == 1) ? 0 : spaceCount % (wordCount - 1);
string ans;
for (int i = bg; i < ed; ++i) { // 除了最后一个单词
ans += words[i];
if (lastLine) {
fill_n(back_inserter(ans), 1, ' '); // 最后一行,每遇到一个单词添加固定1个空格即可
continue;
}
fill_n(back_inserter(ans), spaceSuffix + spaceAvg + ((i - bg) < spaceExtra), ' '); // 非最后一行
}
ans += words[ed]; // 添加最后一个单词
fill_n(back_inserter(ans), maxWidth - ans.size(), ' '); // 一行只有一个单词/最后一行 要把右边的空格填补起来
return ans;
}
vector<string> fullJustify(vector<string>& words, int maxWidth) {
vector<string> ans;
int cnt = 0;
int bg = 0;
for (int i = 0; i < words.size(); ++i) {
cnt += words[i].size() + 1;
if (i + 1 == words.size() || cnt + words[i + 1].size() > maxWidth) {
ans.push_back(fillWords(words, bg, i, maxWidth, i + 1 == words.size()));
bg = i + 1;
cnt = 0;
}
}
return ans;
}
};
其中,
fill_n
是 C++ 中的一个算法函数,用于将指定数量的元素设置为特定的值。
first
:要填充的起始位置的迭代器。
count
:要填充的元素数量。
value
:要填充的值。back_inserter
是 C++ 标准库中的一个函数模板,位于<iterator>
头文件中,用于创建一个插入迭代器,该迭代器可以用于在容器的末尾插入元素。back_inserter
函数接受一个容器x
,并返回一个插入迭代器,该迭代器会在容器x
的末尾插入元素。
- Java版本
class Solution {
public String fillWords(String[] words, int bg, int ed, int maxWidth, boolean lastLine) {
String ans = new String();
int wordCount = ed - bg + 1;
int spaceCount = maxWidth + 1 - wordCount;
for (int i = bg; i <= ed; ++i) {
spaceCount -= words[i].length();
}
int spaceSuffix = 1;
int spaceAvg = (wordCount == 1) ? 0 : spaceCount / (wordCount - 1);
int spaceExtra = (wordCount == 1) ? 0 : spaceCount % (wordCount - 1);
for (int i = bg; i < ed; ++i) {
ans += words[i];
if (lastLine) {
ans += ' ';
continue;
}
for (int j = 0; j < spaceSuffix + spaceAvg + (((i - bg) < spaceExtra) ? 1 : 0); ++j) {
ans += ' ';
}
}
ans += words[ed];
for (int j = ans.length(); j < maxWidth; ++j) {
ans += ' ';
}
return ans;
}
public List<String> fullJustify(String[] words, int maxWidth) {
List<String> ans = new ArrayList<> ();
int cnt = 0;
int bg = 0;
for (int i = 0; i < words.length; ++i) {
cnt += words[i].length() + 1;
if (i + 1 == words.length || cnt + words[i + 1].length() > maxWidth) {
ans.add(fillWords(words, bg, i, maxWidth, i + 1 == words.length));
bg = i + 1;
cnt = 0;
}
}
return ans;
}
}
注意:
- String[]的长度是.length,而String的长度是.length()
- 关于List和ArrayList的区别