題目:
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.
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.
題解:
下面講解引用自Code Ganker(http://blog.csdn.net/linhuanmars/article/details/24063271),代碼部分我用注釋都解釋了下。
“這 道題屬於純粹的字符串操作,要把一串單詞安排成多行限定長度的字符串。主要難點在於空格的安排,首先每個單詞之間必須有空格隔開,而當當前行放不下更多的 單詞並且字符又不能填滿長度L時,我們要把空格均勻的填充在單詞之間。如果剩余的空格量剛好是間隔倍數那么就均勻分配即可,否則還必須把多的一個空格放到 前面的間隔里面。實現中我們維護一個count計數記錄當前長度,超過之后我們計算共同的空格量以及多出一個的空格量,然后將當行字符串構造出來。最后一 個細節就是最后一行不需要均勻分配空格,句尾留空就可以,所以要單獨處理一下。時間上我們需要掃描單詞一遍,然后在找到行尾的時候在掃描一遍當前行的單 詞,不過總體每個單詞不會被訪問超過兩遍,所以總體時間復雜度是O(n)。而空間復雜度則是結果的大小(跟單詞數量和長度有關,不能准確定義,如果知道最 后行數r,則是O(r*L))。代碼如下:”
代碼如下:
2 ArrayList<String> res = new ArrayList<String>();
3 if(words== null || words.length==0)
4 return res;
5 int count = 0;
6 int last = 0;
7 for( int i=0;i<words.length;i++){
8 // count是上一次計算的單詞的長度,words[i].length()是當前嘗試放的一個單詞的長度,
9 // 假設當前放上了這個單詞,那么這一行單詞跟單詞間的間隔數就是i-last
10 // 判斷這些總的長度加起來是不是大於L(超行數了)
11 if(count + words[i].length() + (i-last) > L){
12 int spaceNum = 0;
13 int extraNum = 0;
14 // 因為嘗試的words[i]失敗了,所以間隔數減1.此時判斷剩余的間隔數是否大於0
15 if( i-last-1 >0){
16 // 是間隔的倍數(為啥要減1,因為嘗試當前words[i]后發現比L長了,
17 // 所以當前這個單詞不能算作這行,所以間隔就減少一個
18 spaceNum = (L-count)/(i-last-1);
19 extraNum = (L-count)%(i-last-1); // 不是倍數的話還要計算
20 }
21 StringBuilder str = new StringBuilder();
22 for( int j=last;j<i;j++){
23 str.append(words[j]);
24 if(j<i-1){ // words[i-1]的話后面就不用填空格了,所以這里j<i-1
25 for( int k=0;k<spaceNum;k++)
26 str.append(" ");
27
28 if(extraNum>0)
29 str.append(" ");
30
31 extraNum--;
32 }
33 }
34
35 // 下面這個for循環作用於一行只有一個單詞還沒填滿一行的情況
36 for( int j=str.length();j<L;j++)
37 str.append(" ");
38
39 res.add(str.toString());
40 count=0;
41 last=i; // 下一個開始的單詞
42 }
43 count += words[i].length();
44 }
45
46 // 處理最后一行
47 StringBuilder str = new StringBuilder();
48 for( int i=last;i<words.length;i++){
49 str.append(words[i]);
50 if(str.length()<L)
51 str.append(" ");
52 }
53 for( int i=str.length();i<L;i++)
54 str.append(" ");
55
56 res.add(str.toString());
57 return res;
58 }
Reference:
http://blog.csdn.net/linhuanmars/article/details/24063271
