Format words into wrapped/justified lines
Company: SoFi
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: medium
Interview Round: Technical Screen
Quick Answer: This question evaluates practical programming skills in string processing, greedy packing, and careful handling of spacing and edge cases, and falls under the Coding & Algorithms domain.
Part 1: Greedy Word Wrap Without Padding
Constraints
- 0 <= len(words) <= 10^4
- 1 <= len(words[i]) <= maxWidth <= 100
- Each word consists of non-space characters only
Examples
Input: (["The", "quick", "brown", "fox", "jumps", "over", "the", "lazy", "dog"], 10)
Expected Output: ["The quick", "brown fox", "jumps over", "the lazy", "dog"]
Explanation: Each line greedily takes as many words as possible without exceeding width 10.
Input: (["a", "bc", "d", "ef"], 4)
Expected Output: ["a bc", "d ef"]
Explanation: Both lines fit exactly into width 4 with one space between words.
Input: (["hello"], 10)
Expected Output: ["hello"]
Explanation: Single-word input returns one line, with no trailing padding.
Input: (["a", "b", "c"], 1)
Expected Output: ["a", "b", "c"]
Explanation: With width 1, every word must appear on its own line.
Input: ([], 5)
Expected Output: []
Explanation: Empty input should produce no lines.
Hints
- Track the total number of letters already in the current line. If you add another word, the number of required spaces is equal to the number of words already in that line.
- When the next word no longer fits, finalize the current line with `' '.join(current_words)` and start a new one.
Part 2: Full Text Justification
Constraints
- 0 <= len(words) <= 10^4
- 1 <= len(words[i]) <= maxWidth <= 100
- Each word consists of non-space characters only
Examples
Input: (["This", "is", "an", "example", "of", "text", "justification."], 16)
Expected Output: ["This\x20\x20\x20\x20is\x20\x20\x20\x20an", "example\x20\x20of\x20text", "justification.\x20\x20"]
Explanation: The expected literal uses `\x20` to make spaces visible. Non-last lines distribute spaces evenly, and the last line is left-justified.
Input: (["What", "must", "be", "acknowledgment", "shall", "be"], 16)
Expected Output: ["What\x20\x20\x20must\x20\x20\x20be", "acknowledgment\x20\x20", "shall\x20be\x20\x20\x20\x20\x20\x20\x20\x20"]
Explanation: The first line gets 3 spaces in each gap, the second is a single-word non-last line padded on the right, and the final line is left-justified.
Input: (["hello"], 8)
Expected Output: ["hello\x20\x20\x20"]
Explanation: A single last line is left-justified and padded to length 8.
Input: (["a", "b", "c"], 1)
Expected Output: ["a", "b", "c"]
Explanation: Each line already has exact width 1, so no extra spaces are needed.
Input: ([], 5)
Expected Output: []
Explanation: Empty input should return an empty list.
Hints
- First, greedily decide which words belong to each line. Then format that line separately.
- For a non-last line with multiple words, let `total_spaces = maxWidth - total_letters`. Use `divmod(total_spaces, gaps)` to know the minimum spaces per gap and how many leftmost gaps get one extra space.