来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/text-justification
题目描述:
给定一个单词数组和一个长度 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 "
]
题目分析:
- 一行只有一个单词word, 剩余空格数 len = maxWidth - word.length;填充到右边。
- 一行有多个单词,假设单词数量为num,则存在num - 1个间隔需要maxWidth - num个单词的长度,需要一次填充到单词的间隔中
- 最后一行,单词之间的间隔占据一个空格,剩下的空格全部填充到右边
思路:
按照上面的三种情况依次实现即可.
代码实现:
class Solution {
public List<String> result = new ArrayList();
public String[] arr;
public int maxWidth;
public List<String> fullJustify(String[] words, int maxWidth_) {
maxWidth = maxWidth_;
arr = words;
int count = 0;
int len = words.length;
int left = 0, right = 0;
while (right < len) {
count += words[right].length(); // 计算单词长度.
count++; // 加上空格
if ((count - 1)> maxWidth) { // 可以写一行
count -= words[right].length();
right--; //上一次单词才是该行最后一个单词
if (left == right) { // 如果一行只有一个单词
oneWord(left);
} else if (left < right) { // 如果一行有多个单词.
manyWord(left, right, count - 2);
}
left = right + 1;
count = 0;
}
right++;
}
lastWord(left, len - 1, count - 1);
return result;
}
public void oneWord(int left) { // 一个单词一行.
StringBuilder sb = new StringBuilder();
sb.append(arr[left]);
int len = arr[left].length();
while (len++ < maxWidth) {
sb.append(" ");
}
result.add(sb.toString());
}
public void manyWord(int left, int right, int count) {
int wordNum = right - left + 1; // 单词数量.
int[] nums = new int[wordNum - 1];
int len = maxWidth - count + wordNum - 1; // 空格数量.
int idx = 0;
while (len-- > 0) {
nums[idx]++;
idx++;
idx %= nums.length;
}
idx = 0;
StringBuilder sb = new StringBuilder();
while (left <= right) {
sb.append(arr[left++]);
if (idx < nums.length) {
int num = nums[idx++];
for (int j = 0; j < num; j++) {
sb.append(" ");
}
}
}
result.add(sb.toString());
}
public void lastWord(int left, int right, int count) {
StringBuilder sb = new StringBuilder();
while (left < right) {
sb.append(arr[left++]).append(" ");
}
sb.append(arr[right]);
while (count++ < maxWidth) {
sb.append(" ");
}
result.add(sb.toString());
}
}