题目来源:https://leetcode-cn.com/problems/text-justification/
大致题意:
给定一个字符数组,和一个行的最大长度。
将单词放入行内,同一行相邻的单词中间需要有空格。当放入一个单词后该行长度大于最大长度,那么这个单词就能放入该行,需要另起一行。
这样的话,行的长度就可能会小于最大长度,于是需要增加单词间的空格数量,尽可能均匀的分配,若不能均匀分配,那么左边的单词数量应该大于右边。
最后一行单词间只需要一个空格,但是最后一个单词后需要补空格,直至行长度等于最大程度。
思路
模拟
注意
- 单词之间加一个空格刚好等于最大长度的情况
- 最后一行的情况
- 只有一个单词的情况
- 左边空格数大于右边的情况
代码:
public List<String> fullJustify(String[] words, int maxWidth) {
int idx = 0;
List<String> ansList = new ArrayList<>();
while (idx < words.length) {
int len = 0; // 该行长度
// 存下该行单词
String[] line = new String[maxWidth / 2 + 1];
int count = 0; // 该行单词数量
StringBuffer sb = new StringBuffer(); // 存下该行
// 取单词
while (len < maxWidth+1 && idx < words.length) { // 若当前长度小于等于最大长度+1(尾部空格)
len += words[idx].length() + 1; // 加上该单词以及一个空格
line[count++] = words[idx++]; // 放入容器
}
if (len <= maxWidth + 1) { // 刚好, 或者是最后一行
for (int i = 0; i < count-1; i++) {
sb.append(line[i] + " ");
}
sb.append(line[count - 1]);
// 若是最后一行,补上尾部空格
for (int i = 0; i < maxWidth+1-len; i++)
sb.append(" ");
}
else { // 大于最大长度,合理布局空格
// 单词数-1,行长度减去尾部单词和尾部空格
len -= line[--count].length() + 1;
// 索引后退一步
idx--;
// 先求出需要空隙个数
int spaceNum = count - 1;
if (spaceNum == 0) { // 只有一个单词
sb.append(line[0]);
for (int i = 0; i > maxWidth - line[0].length(); i++)
sb.append(" ");
}
else {
// 求出当前长度和行长的差值
int diff = maxWidth - len + 1; // 尾部无空格,需要+1
// 存余数,若除不尽,代表左端的空格数大于右端
int rest = diff % spaceNum;
// 存除数
int space = diff / spaceNum + 1;
for (int i = 0; i < count - 1; i++) {
sb.append(line[i]);
// 加空格
if (rest > i) // 有余数,左边多加一个
sb.append(" ");
for (int j = 0 ; j < space; j++) {
sb.append(" ");
}
}
sb.append(line[count-1]);
}
}
ansList.add(sb.toString());
}
return ansList;
}