</> MAANG.io
coding interview · 301

Advanced

Advanced coding interview preparation covering complex algorithms, system design, and optimization techniques for senior-level positions.

0/95 solved 0% complete

Simulation and Layout

What is this?

Three problems where the specification is the algorithm. Text justification has three separate rules about where spaces go and every one of them is a distinct code path. The robot asks about infinite repetition and needs a single pass. Sparse multiplication is textbook matrix multiplication with the zeros skipped — which requires reordering the loops so that skipping is possible.

None of these rewards cleverness. They reward getting every case right the first time.

Simulation and Layout rule tree for justification, robot, and sparse matrix

💡 Fun fact: Sparse Matrix Multiplication becomes efficient through a loop reorder, not a data structure. The textbook i, j, k order computes one output cell at a time and must touch every k regardless. Swapping to i, k, j puts A[i][k] in the outer position — so when it is zero, the entire inner loop over j is skipped, because a zero contributes nothing to any output cell in that row. Same arithmetic, same results, and the work drops to the number of non-zero entries. The i, k, j ordering is also the cache-friendlier one on dense matrices, which is why numerical libraries use it anyway.

🔓 The 3 problems in this chapter are free. Sign in with Google or Microsoft to start solving.


The one-line idea: enumerate the cases on paper first. In this chapter the specification is the algorithm, and every failure is a rule discovered halfway through an implementation.


1. Three rules about spaces

if width + len(line) + len(word) > maxWidth:      # len(line) = minimum 1 space per gap
    if len(line) == 1:
        out.append(line[0].ljust(maxWidth))       # rule 2: single word, pad right
    else:
        spaces, gaps = maxWidth - width, len(line) - 1
        q, r = divmod(spaces, gaps)               # q each, plus one extra for the first r
        out.append("".join(line[i] + " " * (q + (i < r)) for i in range(gaps)) + line[-1])
    line, width = [], 0
line.append(word); width += len(word)
...
out.append(" ".join(line).ljust(maxWidth))        # rule 1: last line, left-justified

divmod does the whole distribution: q spaces in every gap, and the remainder r handed one at a time to the leftmost gaps. That left-loading is the rule most often missed, and it is a single (i < r).

The overflow test uses len(line) as the count of minimum single spaces already committed — one per gap plus one for the word about to be added — which is why it reads as width + len(line) + len(word).

2. One pass settles infinity

x = y = 0; dx, dy = 0, 1                          # facing north
for c in instructions:
    if   c == 'G': x, y = x + dx, y + dy
    elif c == 'L': dx, dy = -dy, dx               # rotate left 90°
    else:          dx, dy = dy, -dx               # rotate right 90°
return (x, y) == (0, 0) or (dx, dy) != (0, 1)

Two acceptance conditions, and the second is the interesting one. If the heading changed, four repetitions of the cycle rotate the same displacement by 90° each time, and four vectors at right angles sum to zero — so the robot returns to the origin no matter what that displacement was. If the heading is unchanged and the position is not, every cycle adds the identical vector and the robot escapes.

Rotation without trigonometry is worth internalising: left is (dx, dy) → (−dy, dx), right is (dx, dy) → (dy, −dx).

3. Skip the zeros by reordering

for i in range(m):
    for k in range(n):
        if A[i][k] == 0: continue                 # ← the entire j loop is skipped
        for j in range(p):
            if B[k][j]: C[i][j] += A[i][k] * B[k][j]

The continue is only possible because k is in the middle rather than innermost. With the textbook i, j, k order the zero check would have to run inside the innermost loop and would save almost nothing.

For genuinely sparse inputs, converting each matrix to a list of (index, value) pairs per row is the further step — and worth mentioning even if you do not write it.


4. A 30-second worked example (justification)

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

Worked text justification example at width 16

Line 2 is the whole chapter in one line of output. The extra space goes into the left gap, giving example two spaces after it and of one — and a solution that loads the remainder to the right produces "example of text", which is 16 characters, looks reasonable, and is wrong.


5. Where you'll actually meet this

  • Typesetting engines. Justification is what word processors, browsers and PDF renderers implement.
  • Terminal and CLI output. Wrapping and aligning help text under a width limit is this code.
  • Robotics safety. Determining whether a repeated command sequence stays within a bounded region is a real pre-flight check.
  • Graph analytics. Sparse matrix multiplication is the core primitive behind PageRank and BFS-as-linear-algebra.
  • Machine learning pipelines. Sparse feature matrices are the normal case, not the exception.

6. Problems in this chapter

▶ Text Justification

Format words into fully justified lines of exact width. Pack greedily, distribute spaces with divmod loading the remainder left, and left-justify the last line.
Pattern: greedy packing + explicit case rules. Target: O(total characters).

▶ Robot Bounded In Circle

Decide whether a repeated instruction sequence keeps the robot bounded. Simulate one cycle; bounded if it returns to the origin or its heading changed.
Pattern: one-pass invariant. Target: O(n) time, O(1) space.

▶ Sparse Matrix Multiplication

Multiply two matrices that are mostly zeros. Loop i, k, j so a zero in A skips an entire inner loop.
Pattern: loop reordering to skip work. Target: proportional to the non-zero count.


7. Common pitfalls 🚫

  • Loading extra spaces to the right. They go to the leftmost gaps.
  • Justifying the last line. It is left-justified and padded on the right.
  • Forgetting the single-word line, which has no gaps and would divide by zero.
  • Simulating the robot for many cycles. One is provably enough.
  • Getting the rotation formulas backwards. Left is (−dy, dx), right is (dy, −dx).
  • Keeping the i, j, k loop order and then wondering why skipping zeros saved nothing.
  • Not padding every line to exactly maxWidth. Trailing spaces are part of the required output.

8. Key takeaways

  1. The specification is the algorithm. Write the cases down before writing code.
  2. divmod distributes remainders — and which side receives them is a stated rule, not a preference.
  3. One pass can decide a question about infinity when the structure repeats.
  4. Four right-angle rotations sum to zero, which is the whole boundedness proof.
  5. Loop order determines what you can skip. Put the value you want to test outside the loop it controls.
  6. Every output line must be exactly the requested width, padding included.
  7. Why interviewers like it: there is nothing to be clever about, so completeness and care are the only things visible.

Order: Text Justification → Robot Bounded In Circle → Sparse Matrix Multiplication.

Text Justification

Core idea: You're given a list of words and a fixed maxWidth. Produce a list of lines, each exactly maxWidth characters wide, fully justified. Two phases. Phase 1 (pack): sweep left to right and greedily grab as many words as fit on the current line — a set of words fits if sum(word lengths) + (gaps between them) <= maxWidth, where the minimum gap count is (number of words - 1) single spaces. Phase 2 (justify): for a line with g gaps you have maxWidth - sum(word lengths) spaces to spread across those g slots; give each slot total_spaces // g spaces, and hand the leftover total_spaces % g spaces one extra each to the leftmost slots (left-biased). Two lines break the rule and are left-justified instead (words joined by single spaces, then right-padded with blanks to maxWidth): the last line, and any line holding a single word (it has zero gaps to spread into). Everything is one linear pass over the words. O(total characters).


Problem, rephrased

You're writing the layout engine for a newspaper column exactly maxWidth characters wide — a hard physical edge the type must meet on both sides. You're given the story as an array of words, in reading order. Pack lines greedily: each line takes as many words as fit, counting the word lengths plus at least one space between neighbours, never exceeding maxWidth.

Return the list of lines, each padded to exactly maxWidth characters and fully justified: distribute the leftover spaces across the gaps between words as evenly as possible, and when they don't divide evenly give the leftmost gaps the extra space — the typesetter's rule that loosens the start of a line first. Two lines are exceptions and are left-justified instead (single spaces between words, blanks padding out the right edge): the last line of the column, and any line holding a single word, which has no gap to absorb slack.

Strip the story away and this is LeetCode 68 — Text Justification: given words and maxWidth, greedily pack the words into lines and return the fully justified text in which every line is exactly maxWidth characters, spaces distributed left-biased, with the last line and one-word lines left-justified.

Input Means Output (each line maxWidth wide)
words = ["This","is","an","example","of","text","justification."], maxWidth = 16 7 words into 16-wide lines ["This is an","example of text","justification. "]
words = ["What","must","be","acknowledgment","shall","be"], maxWidth = 16 note the last line ["What must be","acknowledgment ","shall be "]
words = ["Science","is","what","we","understand","well","enough","to","explain","to","a","computer."], maxWidth = 20 wider column (see Example 3)

Note every output string is exactly maxWidth long — that invariant is the single best thing to assert when you test.


Sign in to continue reading

The rest of this lesson is available with a free account. Signing in with Google or Microsoft is free.

Sign in to read the full lesson

Sign in to MAANG.io

Use your Google or Microsoft account — no password to remember.

Continue with Google Continue with Microsoft

Please accept the terms above to continue.