Leetcode: 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 exactly L 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.

click to show corner cases.

Corner Cases:
A line other than the last line might contain only one word. What should you do in this case?
In this case, that line should be left-justified.

难度:100,算法上倒没什么,但是处理起来细节太多。程序功能类似word文档的两边对齐功能。

主要难点在于空格的安排,首先每个单词之间必须有空格隔开,而当当前行放不下更多的单词并且字符又不能填满长度L时,我们要把空格均匀的填充在单词之间。如果剩余的空格量刚好是间隔倍数那么就均匀分配即可,否则还必须把多的空格放到前面的间隔里面。

count来表示累积的word的character sum,用一行L-count就是这一行空格的总和,除以空格数就是每个空格平均大小,求余就是extra space均匀分到前面的空格里面

 1 public class Solution {
 2     public List<String> fullJustify(String[] words, int L) {
 3         ArrayList<String> res = new ArrayList<String>();
 4         if (words==null || words.length==0) {
 5             return res;
 6         }
 7         int count = 0; //totoal num of characters of words in a line, L-count = total num of spaces
 8         int last = 0; //denote the position of String[] words where this line starts with
 9         for (int i=0; i<words.length; i++) {
10             if (count+words[i].length()+i-last > L) { //try to add words[i] to the line but fail, so this line contains word[last] to word[i-1] and spaces
11                 int averSpace = 0;
12                 int extraSpace = 0;
13                 if (i-last-1 > 0) { //this line contains at least two words and one interval, should be central justified
14                     averSpace = (L-count)/(i-last-1);  //average space size
15                     extraSpace = (L-count)%(i-last-1); //extra space size, assigned 1 to each of the spaces except the last one
16                 }
17                 StringBuffer strbuf = new StringBuffer();
18                 for (int j=last; j<i; j++) {
19                     strbuf.append(words[j]);
20                     if (j < i-1) { //no need to add space after the last word of this line
21                         for (int k=0; k<averSpace; k++) {
22                             strbuf.append(" ");
23                         } 
24                         if (extraSpace > 0) { //each space/interval(except last one) can share 1 space of this extraSpace 
25                             strbuf.append(" ");
26                         }
27                         extraSpace--;
28                     }
29                 }
30                 
31                 for (int j=strbuf.length(); j<L; j++) {//A line other than last line contains only one word, and is left justified. 
32                     strbuf.append(" ");
33                 }
34                 count = 0; //finish processing this line, update count and last for the next line
35                 last = i;
36                 res.add(strbuf.toString());
37             }
38             count += words[i].length();
39         }
40         
41         StringBuffer lastline = new StringBuffer(); //deal with last line. This line's length may nor reach L, should fill ' ' to fill.
42         for (int j=last; j<words.length; j++) {
43             lastline.append(words[j]);
44             if (j < words.length-1) lastline.append(" ");
45         }
46         for (int j=lastline.length(); j<L; j++) {
47             lastline.append(" ");
48         }
49         res.add(lastline.toString());
50         return res;
51     }
52 }