用「快刷四部曲」把 1361 题(文字并排,68 号原题复刻版)5 分钟速刷掉。
核心模板:贪心装行 → 算空槽 → 算平均/余量 → 最后一行左对齐。
① 抽象模型
- 每行尽可能多装单词,单词间至少 1 个空格。
- 非末行:总空格
totalSpaces = maxWidth - sum(len(words)),空槽gaps = wordCount-1。
平均base = totalSpaces / gaps,余量extra = totalSpaces % gaps,前 extra 个空槽多塞 1 个空格。 - 末行:左对齐,单词间单空格,右侧统一补空格到 maxWidth。
- 单行即末行处理。
② 最优算法
时间 O(N·L)(N 单词数,L 平均长度),空间 O(1) 除输出外。
算法:
- 双指针 i,j 找一行能装下的最右单词。
- 计算该行单词总长度 sumLen,空格总数 spaces = maxWidth - sumLen。
- 若 j 到末尾 或 该行仅 1 个单词 → 末行格式。
- 否则按 base + (idx < extra ? 1 : 0) 分配空格。
- StringBuilder 拼行,加入结果列表。
③ 边界/异常
- words == null || words.length == 0 ⇒ 返回空列表。
- maxWidth < 最短单词长度 ⇒ 题目保证合法,无需处理。
④ 代码(Java,可直接粘 LintCode)
java
public List<String> fullJustify(String[] words, int maxWidth) {
List<String> ans = new ArrayList<>();
int n = words.length, i = 0;
while (i < n) {
int j = i, len = 0;
// 1. 贪心装一行
while (j < n && len + words[j].length() + (j - i) <= maxWidth) {
len += words[j++].length();
}
int gaps = j - i - 1; // 空槽数
int spaces = maxWidth - len; // 总空格
StringBuilder line = new StringBuilder();
// 2. 末行 or 单行
if (j == n || gaps == 0) {
for (int k = i; k < j; k++) {
line.append(words[k]);
if (k + 1 < j) line.append(' ');
}
while (line.length() < maxWidth) line.append(' ');
} else {
// 3. 均匀分空格
int base = spaces / gaps, extra = spaces % gaps;
for (int k = i; k < j; k++) {
line.append(words[k]);
if (k + 1 < j) {
for (int x = 0; x < base; x++) line.append(' ');
if (extra-- > 0) line.append(' ');
}
}
}
ans.add(line.toString());
i = j;
}
return ans;
}
复杂度:
时间 O(N·L),空间 O(1) 除输出。
写完,Submit,一遍 AC。