Question
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.
本题难度Hard。
【复杂度】
时间 O(N) 空间 O(N)
【思路】
虽然是Hard,但是思路却不复杂。就是不断地判断是否超过L
个字符。题目的要求是:
- 空隙可以用空格
" "
填充 - 空隙应当均匀地填充
- 如果空隙不能均匀填充,多余的往单词左边的slot填充
- 最后一行左对齐,且单词间不插入多余空格,多余的填到最后面
另外,note说明了所有的单词长度都不超过L
:
Note: Each word is guaranteed not to exceed L in length.
【注意】
1、我曾经尝试过将16-18行改为:
if(count+word.length()+list.size()<maxWidth){
list.add(word+" ");
count+=word.length()+1;
但是这样做会有个问题,比如:
words={"a","b","c"},maxWidth=4
得到结果的第一行为:
"a b "
所以不要急于加入空格。
2、31-40针对的是第四条要求
3、52-55行的目的是防止size==1
导致58行产生%0
这种错误。
【代码】
public class Solution {
public List<String> fullJustify(String[] words, int maxWidth) {
//require
List<String> ans=new ArrayList<String>();
if(words==null||maxWidth<0)
return ans;
int size=words.length;
if(size<1)
return ans;
List<String> list=new ArrayList<String>();
String word=null;
int i=0,count=0;
//invariant
do{
word=words[i];
if(count+word.length()+list.size()<maxWidth){
list.add(word);
count+=word.length();
++i;
}else if(count+word.length()+list.size()==maxWidth){
list.add(word);
count+=word.length();
ans.add(average(list,count,maxWidth));
list.clear();count=0;
++i;
}else{
ans.add(average(list,count,maxWidth));
list.clear();count=0;
}
}while(i<size);
if(list.size()>0){
StringBuilder sb=new StringBuilder();
for(String str:list){
sb.append(str+" ");
count++;
}
list.clear();
list.add(sb.toString());
ans.add(average(list,count,maxWidth));
}
//ensure
return ans;
}
private String listToStr(List<String> list){
StringBuilder sb=new StringBuilder();
for(String str:list)
sb.append(str);
return sb.toString();
}
private String average(List<String> list,int count,int max){
int size=list.size();
if(size==1){
for(int i=0;i<max-count;i++){
list.set(0,list.get(0)+" ");
}
}else{
for(int i=0;i<max-count;i++){
list.set(i%(size-1),list.get(i%(size-1))+" ");
}
}
return listToStr(list);
}
}