package com.interview.leetcode.strings; import java.util.ArrayList; /** * Created_By: stefanie * Date: 14-11-17 * Time: 上午11:13 * * 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. * * Solution: * 1. scan the words, tracking current len and word count k. * when current len > L, pack the previous k words to a line, continue. (notice, should add ' ' length when cal > L) * until the last word, add ' ' to the end * 2. when pack k words to a line, calculate the ' ' spot number, and how many ' ' in each spot * when spot == 1 or it contains last word, add ' ' in every spot, and append ' ' at the end * when spot > 1, add ' ' * (total space/spot) in each spot, and append the extra at the last spot * * Tricks: * 1. not difficult, not little bit complicated for different cases. */ public class TextJustification { public ArrayList<String> fullJustify(String[] words, int L) { int wordsCount = words.length; ArrayList<String> result = new ArrayList<String>(); int curLen = 0; int begin = 0; for (int i = 0; i <= wordsCount; i++) { if (i == wordsCount || curLen + words[i].length() + i - begin > L) { //store prev words StringBuffer buf = new StringBuffer(); int spaceCount = L - curLen; int spaceSlots = i - begin - 1; if (spaceSlots == 0 || i == wordsCount) { //i == wordsCount is a last word for (int j = begin; j < i; j++) { buf.append(words[j]); if (j != i - 1) appendSpace(buf, 1); } appendSpace(buf, L - buf.length()); } else { int spaceEach = spaceCount / spaceSlots; int spaceExtra = spaceCount % spaceSlots; for (int j = begin; j < i; j++) { buf.append(words[j]); if (j != i - 1) appendSpace(buf, spaceEach + (j - begin < spaceExtra ? 1 : 0)); } } result.add(buf.toString()); begin = i; curLen = 0; } if (i < wordsCount) curLen += words[i].length(); } return result; } private void appendSpace(StringBuffer sb, int count) { for (int i = 0; i < count; i++) sb.append(' '); } }