领英面试题:文字并排
描述
给定一个单词数组和一个宽度maxWidth,格式化文本,使每行具有刚好maxWidth个字符并完全(左和右)对齐。
你应该用贪心法打包你的单词; 也就是说,在每行中包含尽可能多的单词。 必要时填充额外的空格,以便每行具有正确的maxWidth字符。
单词之间的额外空格应尽可能均匀分布。 如果一行上的空格数不均匀分配,则左侧的空插槽将分配比右侧插槽更多的空格。
对于最后一行文本,它应该是左对齐的,并且在单词之间不插入额外的空格。
·单词定义为仅由非空格字符组成的字符序列。
·每个单词的长度保证大于0且不超过maxWidth。
·输入数组words至少包含一个单词。
样例1
输入:
words = ["This", "is", "an", "example", "of", "text", "justification."]
maxWidth = 16
输出:
[
"This is an",
"example of text",
"justification. "
]
样例 2:
输入:
words = ["What","must","be","acknowledgment","shall","be"]
maxWidth = 16
输出:
[
"What must be",
"acknowledgment ",
"shall be "
]
说明:请注意,最后一行是 "shall be " 而不是 "shall be",
因为最后一行必须左对齐而不是完全对齐。
请注意,第二行也是左对齐的,因为它只包含一个单词。
样例 3:
输入:
words = ["Science","is","what","we","understand","well","enough","to","explain",
"to","a","computer.","Art","is","everything","else","we","do"]
maxWidth = 20
输出:
[
"Science is what we",
"understand well",
"enough to explain to",
"a computer. Art is",
"everything else we",
"do "
]
解题思路
本题我们需要按照题目意思进行模拟,首先我们尽可能多的在一行内多放单词,如果不能放的话,我们就考虑空格的计算,尽可能的均摊,然后多余的按照题意数处理
总体复杂度O(n)
源代码
public class Solution {
public ArrayList<String> fullJustify(String[] words, int L) {
int wordsCount = words.length; //获取单次数量
ArrayList<String> result = new ArrayList<String>(); //统计答案
int curLen = 0;
int lastI = 0;
for (int i = 0; i <= wordsCount; i++) {
if (i == wordsCount || curLen + words[i].length() + i - lastI > L) { //判断单行是否允许再放一个单词
StringBuffer buf = new StringBuffer();
int spaceCount = L - curLen;
int spaceSlots = i - lastI - 1;
if (spaceSlots == 0 || i == wordsCount) {
for(int j = lastI; j < i; j++){
buf.append(words[j]);
if(j != i - 1)
appendSpace(buf, 1);
}
appendSpace(buf, L - buf.length());
} else {
int spaceEach = spaceCount / spaceSlots; //如果不能,计算空格的数量和位置
int spaceExtra = spaceCount % spaceSlots;
for (int j = lastI; j < i; j++) {
buf.append(words[j]);
if (j != i - 1)
appendSpace(buf, spaceEach + (j - lastI < spaceExtra ? 1 : 0));
}
}
result.add(buf.toString());
lastI = i;
curLen = 0;
}
if (i < wordsCount)
curLen += words[i].length();
}
return result;
}
private void appendSpace(StringBuffer sb, int count) {
for (int i = 0; i < count; i++)
sb.append(' ');
}
}