96. Text Justification
hardAsked at SnowflakePack words greedily into lines of exactly maxWidth characters, distributing the leftover spaces as evenly as possible with a left bias — then break your own rules for single-word lines and the final line. Snowflake candidates report this hard not for algorithmic depth but for specification discipline: three special cases, each easy to miss, graded the way a result-set pretty-printer or fixed-width unload formatter would be — by whether every byte lands exactly where the spec says.
By Sam K., Founder, InterviewChamp.AI · Last verified
Source citations
Public interview reports confirming this problem appears in Snowflake loops.
- Glassdoor (2025-Q4)— Snowflake unload-team uses this in onsites.
- LeetCode Discuss (2025-09)— Reported at Snowflake SDE-II screens.
Problem
Given an array of strings words and a width maxWidth, format the text such that each line has exactly maxWidth characters and is fully (left and right) justified. You should pack your words in a greedy approach. Pad extra spaces ' ' when necessary so that each line has exactly maxWidth characters. Extra spaces between words should be distributed as evenly as possible. The last line of text and lines with a single word should be left-justified.
Constraints
1 <= words.length <= 3001 <= words[i].length <= 20words[i] consists of only English letters and symbols.1 <= maxWidth <= 100words[i].length <= maxWidth
Examples
Example 1
words = ["This", "is", "an", "example", "of", "text", "justification."], maxWidth = 16["This is an","example of text","justification. "]Explanation: Line 1 has 2 gaps sharing 8 spaces (4+4); line 2's three words leave 3 spaces split 2+1 with the left bias; the last line is left-justified and right-padded — all three spacing regimes in one example.
Example 2
words = ["What","must","be","acknowledgment","shall","be"], maxWidth = 16["What must be","acknowledgment ","shall be "]Explanation: 'acknowledgment' sits alone on its line — the single-word rule kicks in (left-justify, pad right) even though it is NOT the last line.
Approaches
1. Pack greedily, distribute spaces
Greedy packing: keep adding words while total + spaces <= maxWidth. Then distribute extra spaces left-biased.
- Time
- O(total chars)
- Space
- O(total chars)
function fullJustify(words, maxWidth) {
const result = [];
let i = 0;
while (i < words.length) {
let j = i, len = words[i].length;
while (j + 1 < words.length && len + 1 + words[j+1].length <= maxWidth) {
len += 1 + words[++j].length;
}
const gaps = j - i;
let line;
if (j === words.length - 1 || gaps === 0) {
// Last line or single word: left-justify
line = words.slice(i, j + 1).join(' ');
line += ' '.repeat(maxWidth - line.length);
} else {
const totalSpaces = maxWidth - len + gaps;
const base = Math.floor(totalSpaces / gaps);
const extra = totalSpaces % gaps;
line = '';
for (let k = i; k <= j; k++) {
line += words[k];
if (k < j) {
const sp = base + (k - i < extra ? 1 : 0);
line += ' '.repeat(sp);
}
}
}
result.push(line);
i = j + 1;
}
return result;
}Tradeoff: Greedy with care on edge cases. The last-line and single-word rules are easy to miss.
2. Round-robin space distribution
Same greedy packing, but distribute spaces by looping over the gaps and dropping one space into each, left to right, until the line reaches maxWidth — no division or remainder math.
- Time
- O(total chars)
- Space
- O(total chars)
function justifyLine(lineWords, maxWidth, isLast) {
if (isLast || lineWords.length === 1) {
const line = lineWords.join(' ');
return line + ' '.repeat(maxWidth - line.length);
}
const gaps = new Array(lineWords.length - 1).fill(1);
let len = lineWords.reduce((a, w) => a + w.length, 0) + gaps.length;
let g = 0;
while (len < maxWidth) {
gaps[g % gaps.length]++;
g++; len++;
}
return lineWords.map((w, k) => k < gaps.length ? w + ' '.repeat(gaps[k]) : w).join('');
}Tradeoff: Trades the base/extra modular arithmetic for a dead-simple loop that cannot get the left bias wrong — at the cost of O(maxWidth) iterations per line instead of O(gaps). At maxWidth <= 100 that difference is irrelevant, so pick whichever you can defend faster under pressure.
Snowflake-specific tips
Snowflake interviewers grade this on edge-case rigor: last-line left-justified, single-word line left-justified, uneven space distribution biased left. Bonus signal: pivot to formatted unload — when Snowflake exports CSV with column padding, the executor follows similar packing-and-distributing logic.
Common mistakes
- Treating the last line like a normal line (must be left-justified).
- Distributing extra spaces evenly even when one word per line (just pad on the right).
- Off-by-one with the +1 for the trailing space between words.
Follow-up questions
An interviewer at Snowflake may pivot to one of these next:
- Right-justify variant.
- Center-justify variant.
- How does Snowflake's CSV unload format fixed-width columns?
Solve it now
Free. No sign-up. Python and JavaScript run instantly in your browser.
FAQ
Why left-bias the extra spaces?
The spec mandates it: when spaces don't divide evenly, the leftmost gaps get the extras. This is a typographic convention.
Why a special case for the last line?
Books and newspapers conventionally leave the last line ragged-right — left-justified with single spaces. The spec follows that convention.
What makes this 'hard' when the algorithm is a simple greedy?
The difficulty is entirely in faithful spec implementation: three spacing regimes (justified, single-word, last line), a left-biased remainder rule, and exact width invariants. Interviewers use it to observe how you organize messy conditional logic — helper functions per regime read far better than one tangled loop.
More Snowflake coding interview questions
- 1. Two Sum
- 2. Valid Parentheses
- 3. Merge Two Sorted Lists
- 4. Remove Duplicates from Sorted Array
- 5. Remove Element
- 6. Search Insert Position
- 7. Plus One
- 8. Merge Sorted Array