思路源自
leetcode-字符串篇 68题 文本左右对齐
难度高的模拟类型题目,关键点在于事先知道有多少单词要放在本行并且还要知道本行是不是最后一行(最后一行需要全部单空格右对齐,不是最后一行就空格均摊),非最后一行的空格要尽可能平等的均摊在相邻单词间的空隙内
class Solution {
private String fillWords(String[] words, int begin, int end, int maxWidth, boolean lastLine) {
int wordCount = end - begin + 1;
//除去每一个单词尾部空格和单词本身长度看看多余多少空格
int extraSpace = maxWidth + 1 - wordCount;
for(int i=begin;i<=end;i++)
extraSpace-=words[i].length();
//额外空格的平均值
int extraSpaceAvg = wordCount > 1 ? extraSpace / (wordCount - 1) : 1;
//额外空格的余数
int extraSpaceExtra = wordCount > 1 ? extraSpace % (wordCount - 1) : 0;
//装填数据,先装填前n-1个,最后一个特殊处理
StringBuilder stringBuilder = new StringBuilder();
for(int i=begin;i<end;i++){
stringBuilder.append(words[i]);
if (lastLine) {
stringBuilder.append(" ");
continue;
}
//单词后的空格个数为基本的1个加上平均的再加上多余的
int n = 1 + extraSpaceAvg + (i - begin < extraSpaceExtra ? 1 : 0);
while (n-->0)
stringBuilder.append(" ");
}
//填入最后一个单词和它的空格
stringBuilder.append(words[end]);
while (stringBuilder.length()<maxWidth)
stringBuilder.append(" ");
return stringBuilder.toString();
}
public List<String> fullJustify(String[] words, int maxWidth) {
List<String> result = new ArrayList<>();
int countLen = 0;//统计当前的单词组是否超过maxWidth
int begin = 0;//单词组的起始单词索引
for (int i = 0; i < words.length; i++) {
countLen += words[i].length() + 1;
//如果是最后一个单词,或者加上下一个单词就超过长度,那么可以凑成一行
if (i + 1 == words.length || countLen + words[i + 1].length() > maxWidth) {
result.add(fillWords(words, begin, i, maxWidth, i + 1 == words.length));
begin = i + 1;
countLen = 0;
}
}
return result;
}
}