95. Text Justification
hardAsked at SalesforceFormat text such that each line has exactly maxWidth characters with full justification. Salesforce uses this as a string-manipulation stress test.
By Alex Chen, Founder, InterviewChamp.AI · Last verified
Source citations
Public interview reports confirming this problem appears in Salesforce loops.
- Glassdoor (2026-Q1)— Salesforce uses text formatting in their email template rendering.
- Blind (2025)— Hard string-manipulation onsite question.
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; that is, pack as many words as you can in each line. 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 should be left-justified, and no extra space is inserted between words.
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. "]Approaches
1. Two-pass: select then format
First pass: group words into lines. Second pass: format each line.
- Time
- O(n)
- Space
- O(n)
function fullJustify(words, maxWidth) {
const result = [];
let i = 0;
while (i < words.length) {
let lineLen = words[i].length, j = i + 1;
while (j < words.length && lineLen + 1 + words[j].length <= maxWidth) {
lineLen += 1 + words[j].length;
j++;
}
const lineWords = words.slice(i, j);
const gaps = lineWords.length - 1;
let line;
if (gaps === 0 || j === words.length) {
line = lineWords.join(' ') + ' '.repeat(maxWidth - lineLen);
} else {
const totalSpaces = maxWidth - lineWords.reduce((s, w) => s + w.length, 0);
const base = Math.floor(totalSpaces / gaps), extra = totalSpaces % gaps;
line = lineWords.reduce((acc, w, idx) => {
if (idx === 0) return w;
return acc + ' '.repeat(base + (idx <= extra ? 1 : 0)) + w;
}, '');
}
result.push(line);
i = j;
}
return result;
}Tradeoff: Greedy line-packing + per-line distribution. Salesforce wants both passes done cleanly.
2. Single pass with running buffer
Process word by word; emit when adding next would overflow.
- Time
- O(n)
- Space
- O(n)
// Similar shape. Mostly identical to two-pass.Tradeoff: No advantage over two-pass.
Salesforce-specific tips
Salesforce uses text justification in email-template rendering and dashboard display. They grade on three things: (1) greedy line-packing logic, (2) extra-space distribution among gaps (extra spaces go to leftmost gaps first), (3) last-line special case (left-justified, no inter-word padding). Bonus signal: walk through the case where a line has only one word — must left-justify and pad with trailing spaces.
Common mistakes
- Forgetting the last-line special case — must be left-justified.
- Distributing extra spaces randomly instead of leftmost-first.
- Off-by-one on lineLen accumulation (+1 for the space).
Follow-up questions
An interviewer at Salesforce may pivot to one of these next:
- Optimal line-breaking with cost function (Knuth's algorithm).
- Soft-wrap a large block of text into a fixed width.
- Render markdown into fixed-width text.
Solve it now
Free. No sign-up. Python and JavaScript run instantly in your browser.
FAQ
Why are extra spaces distributed leftmost-first?
Convention — leftmost gaps get rounded-up shares. So if there are 7 spaces over 3 gaps, the first gap gets 3, the second and third get 2 each.
What if a single word equals maxWidth?
It fills the line by itself, no spaces needed. Edge case worth confirming with the interviewer.
Practice these live with InterviewChamp.AI
Drill Text Justification and other Salesforce interview questions under real-loop conditions with instant feedback on your reasoning, complexity claims, and code.
Practice these live with InterviewChamp.AI →