[LeetCode] Text Justification (put words in lines with same length)
解答从这里来
比较麻烦的字符串细节实现题。需要解决以下几个问题:
-
首先要能判断多少个word组成一行:
这里统计读入的所有words的总长curLen,并需要计算空格的长度。假如已经读入words[0:i]。当curLen + i <=L 且加curLen + 1 + word[i+1].size() > L时,一行结束。 -
知道一行的所有n个words,以及总长curLen之后要决定空格分配:
平均空格数:k = (L - curLen) / (n-1)
前m组每组有空格数k+1:m = (L - curLen) % (n-1)
例子:L = 21,curLen = 14,n = 4
k = (21 - 14) / (4-1) = 2
m = (21 - 14) % (4-1) = 1
A—B–C–D
- 特殊情况:
(a) 最后一行:当读入到第i = words.size()-1 个word时为最后一行。该行k = 1,m = 0
(b) 一行只有一个word:此时n-1 = 0,计算(L - curLen)/(n-1)会出错。该行k = L-curLen, m = 0
(c) 当word[i].size() == L时.
public ArrayList<String> fullJustify(String[] words, int L) { ArrayList<String> res = new ArrayList<String>(); if(words==null || words.length==0) return res; //count is the current length of total words length of current round(line) int count = 0; // last the last word's index from last round (line) //well.. it is a actually the first one in this round int last = 0; for(int i=0;i<words.length;i++) { //here it is the whole length if adding current word at index i //i-last is the # of space, need to ensure each empty spot has at least one space if(count+words[i].length()+(i-last)>L) { int spaceNum = 0; int extraNum = 0; //if there is more than one word (deal with the special case later) if(i-last-1>0) { //every slot has spaceNum of space spaceNum = (L-count)/(i-last-1); //the first extraNum of slot has 1 extra space extraNum = (L-count)%(i-last-1); } StringBuilder str = new StringBuilder(); for(int j=last;j<i;j++) { str.append(words[j]); if(j<i-1) { for(int k=0;k<spaceNum;k++) { str.append(" "); } //append an extra space if(extraNum>0) { str.append(" "); } extraNum--; } } //this is only for the special case where there is only one word in the line for(int j=str.length();j<L;j++) { str.append(" "); } res.add(str.toString()); count=0; last=i; } //no matter we reach the end (count is reset to 0) or not (keep increment i), we need to add the length to count. count += words[i].length(); } //deal with the last row StringBuilder str = new StringBuilder(); //will only run if there is more word to put in. //It will reach here only because the length "count+words[i].length()+(i-last)" didn't reach the threshold L for(int i=last;i<words.length;i++) { str.append(words[i]); if(str.length()<L) str.append(" "); } for(int i=str.length();i<L;i++) { str.append(" "); } res.add(str.toString()); return res; }