https://leetcode.com/problems/text-justification/
Given an array of words and a length L, format the text such that each line has exactly L characters and is fully (left and right) justified.
You should pack your words in a greedy approach; that is, pack as many words as you can in each line. Pad extra spaces ' '
when necessary so that each line has exactlyL characters.
Extra spaces between words should be distributed as evenly as possible. If the number of spaces on a line do not divide evenly between words, the empty slots on the left will be assigned more spaces than the slots on the right.
For the last line of text, it should be left justified and no extra space is inserted between words.
For example,
words: ["This", "is", "an", "example", "of", "text", "justification."]
L: 16
.
Return the formatted lines as:
[ "This is an", "example of text", "justification. " ]
Note: Each word is guaranteed not to exceed L in length.
解题思路:
这是一道实现题,而非算法题。
做出来大概也四五十分钟,比想象的好点。有点技巧的就在于空格无法正好分布的时候的处理,即将余数的空格数量分布在前面的空格里,每个空格多一个。比如2个空格,11个余量,那么就要4、4、3这样分布。因为11/3 == 3;11%3==2。
其他就是一些细节需要注意的,在注释里写了。
public class Solution { public List<String> fullJustify(String[] words, int maxWidth) { List<String> result = new ArrayList<String>(); int currentLength = 0, start = 0, end = 0; for(int i = 0; i < words.length; i++) { if(currentLength == 0) { currentLength = words[i].length(); } else { currentLength += words[i].length() + 1; //除了第一个word,前面都加上空格 } // 一旦宽度已经比maxWidth大,立刻退回一个,开始处理并作为一行插入result if(currentLength > maxWidth) { end = i - 1; StringBuffer currentLine = new StringBuffer(); // 如果只有一个词,直接插入,后面加上n个空格 if(start == end) { currentLine.append(words[start]); for(int j = words[start].length(); j < maxWidth; j++) { currentLine.append(" "); } result.add(currentLine.toString()); } else { // 退回当前词的宽度,并删除前面一个空格 int totalWordsWidth = currentLength - words[i].length() - 1 - (end - start); int baseGap = (maxWidth - totalWordsWidth) / (end - start); int addGap = (maxWidth - totalWordsWidth) % (end - start); for(int j = 0; j <= end - start; j++) { currentLine.append(words[start + j]); for(int k = 0; k < baseGap && j != end - start; k++) { //最后一个词后不要加空格了 currentLine.append(" "); } // 将多出的n个空格,前n个空格,每个空格加一个 if(addGap > 0) { currentLine.append(" "); addGap--; } } result.add(currentLine.toString()); } start = i; currentLength = words[i].length(); } } // 因为上面的判断条件是currentLength > maxWidth,所以这里无论如何最后一行都要单独列出来处理 // 最后一行或者正好==maxWidth或者<maxWidth,都会因为已经到words结尾,退出循环 end = words.length - 1; StringBuffer currentLine = new StringBuffer(); for(int i = start; i <= end; i++) { if(i == start) { currentLine.append(words[i]); } else { currentLine.append(" "); currentLine.append(words[i]); } } // 最后一行无需考虑居中对齐了,只要左对齐即可 for(int i = currentLength; i < maxWidth; i++) { currentLine.append(" "); } result.add(currentLine.toString()); return result; } }