題目:
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