InterviewPrepKit

Home / Coding / Stack

Decode String

medium Original β†—
Solving tips
  • Recognize nested delimiters as a stack problem: at each '[' suspend the string built so far plus the count you just read, and at ']' resume that most-recent frame.
  • Accumulate multi-digit counts with num = num*10 + int(ch), not num = int(ch), and reset cur and num to empty after pushing on '['.
  • On ']' the combine order is prev + cur * k (not cur * k + prev), and the count applies to the whole block so don't multiply early at '['.
  • Target O(m) time and space where m is the decoded output length; the equivalent recursive-descent version just lets the call stack do the bookkeeping.

Problem

You get an encoded string that uses the rule k[segment]: the segment inside the square brackets is repeated exactly k times (k is a positive integer, always present before a [). Encodings can nest β€” a bracketed segment may itself contain more k[...] blocks. Plain lowercase letters outside any brackets are copied through unchanged, and digits appear only as repeat counts.

Return the fully decoded string. The input is guaranteed well-formed.

Examples

  • "3[a]2[bc]" β†’ "aaabcbc" β€” a three times, then bc twice.
  • "3[a2[c]]" β†’ "accaccacc" β€” inner 2[c] becomes cc, so the outer block repeats acc three times.
  • "2[abc]3[cd]ef" β†’ "abcabccdcdcdef" β€” two blocks, then a plain tail ef.

Constraints

  • 1 <= s.length <= 30
  • 1 <= k <= 300; the decoded output is guaranteed to fit (at most ~10^5 characters)
  • s contains only lowercase letters, digits, and square brackets, and is always valid

The input is tiny, but nesting means the output can be large β€” the expected solution is a single left-to-right pass, linear in the output size.

Think about it first

Hint 1 `"3[a2[c]]"` can't be decoded left to right naively: when you meet the first `]`... which `[` does it close? The most recently opened one β€” that word again.
Hint 2 Build the current segment as you scan. When you hit `[`, you must *suspend* what you've built (and the repeat count you just read) and start fresh; when you hit `]`, you resume the suspended work. Suspend/resume in last-in-first-out order is a stack of `(previous_string, count)` frames.
Hint 3 One pass: accumulate multi-digit `num` on digits; on `[` push `(current, num)` and reset both; on `]` pop `(prev, k)` and set `current = prev + current * k`; on a letter, append it. `current` at the end is the answer.
Your workspace Not runnable by design β€” this is your interview scratchpad. Saved on this device.