Skip to main content

93. Text Justification

hardAsked at Plaid

Format text into fully justified lines of fixed width. Plaid asks this as a careful greedy + arithmetic problem — the same flavor of edge-case discipline they need when formatting tabular statement output for end users.

By Alex Chen, Founder, InterviewChamp.AI · Last verified

Source citations

Public interview reports confirming this problem appears in Plaid loops.

  • Glassdoor (2025)Plaid hard string OA.
  • LeetCode Discuss (2026)Plaid edge-case-discipline screen.

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. Pad extra spaces between words. If a line has only one word, left-justify it. The last line is left-justified, not fully justified.

Constraints

  • 1 <= words.length <= 300
  • 1 <= words[i].length <= 20
  • words[i] consists of only English letters and symbols.
  • 1 <= maxWidth <= 100
  • words[i].length <= maxWidth

Examples

Example 1

Input
words = ["This", "is", "an", "example", "of", "text", "justification."], maxWidth = 16
Output
["This    is    an","example  of text","justification.  "]

Approaches

1. Build then post-process

Build word-per-line groups, then pad each line.

Time
O(n)
Space
O(n)
// Single approach below.

Tradeoff: Single approach — no faster algorithm; just careful code.

2. Greedy word packing + per-line justify

Greedily pack words into a line while they fit (with at least 1 space). When full, distribute extra spaces. Last line is left-justified.

Time
O(n * w)
Space
O(n)
function fullJustify(words, maxWidth) {
  const lines = [];
  let i = 0;
  while (i < words.length) {
    let len = words[i].length;
    let j = i + 1;
    while (j < words.length && len + 1 + words[j].length <= maxWidth) {
      len += 1 + words[j].length;
      j++;
    }
    const lineWords = words.slice(i, j);
    const gaps = lineWords.length - 1;
    let line;
    if (j === words.length || gaps === 0) {
      line = lineWords.join(' ') + ' '.repeat(maxWidth - len);
    } else {
      const spaces = maxWidth - (len - gaps);
      const base = Math.floor(spaces / gaps);
      const extra = spaces % gaps;
      line = '';
      for (let k = 0; k < lineWords.length; k++) {
        line += lineWords[k];
        if (k < gaps) line += ' '.repeat(base + (k < extra ? 1 : 0));
      }
    }
    lines.push(line);
    i = j;
  }
  return lines;
}

Tradeoff: Single pass over words. Per-line, the space distribution is deterministic. Edge cases (single word, last line) are explicit branches.

Plaid-specific tips

Plaid grades this on whether you enumerate the three edge cases upfront: single-word line, last line, and normal lines. Bonus signal: walk through with maxWidth=16 to show your space-distribution math is right. Connect to formatted statement-output where columns must align across rows of varying content.

Common mistakes

  • Off-by-one on the gap count (n words = n-1 gaps).
  • Forgetting that last line and single-word lines are left-justified.
  • Computing base = Math.ceil(spaces/gaps) — should be floor, with extra going to leftmost gaps.

Follow-up questions

An interviewer at Plaid may pivot to one of these next:

  • Center-justify.
  • Streaming version — output a line as soon as it's ready.
  • Variable-width fonts — replace char count with pixel width.

Solve it now

Free. No sign-up. Python and JavaScript run instantly in your browser.

Output

Press Run or Cmd+Enter to execute

FAQ

Why do leftmost gaps get the extra space?

Convention. The 'extra' is the remainder after even distribution; spreading it to the left makes the output deterministic.

Single-word line handling?

No gaps to distribute, so pad all extra to the right (left-justify).

Practice these live with InterviewChamp.AI

Drill Text Justification and other Plaid interview questions under real-loop conditions with instant feedback on your reasoning, complexity claims, and code.

Practice these live with InterviewChamp.AI →