|
| 1 | +[](https://github.com/javadev/LeetCode-in-All) |
| 2 | +[](https://github.com/javadev/LeetCode-in-All/fork) |
| 3 | + |
| 4 | +## 394\. Decode String |
| 5 | + |
| 6 | +Medium |
| 7 | + |
| 8 | +Given an encoded string, return its decoded string. |
| 9 | + |
| 10 | +The encoding rule is: `k[encoded_string]`, where the `encoded_string` inside the square brackets is being repeated exactly `k` times. Note that `k` is guaranteed to be a positive integer. |
| 11 | + |
| 12 | +You may assume that the input string is always valid; there are no extra white spaces, square brackets are well-formed, etc. Furthermore, you may assume that the original data does not contain any digits and that digits are only for those repeat numbers, `k`. For example, there will not be input like `3a` or `2[4]`. |
| 13 | + |
| 14 | +The test cases are generated so that the length of the output will never exceed <code>10<sup>5</sup></code>. |
| 15 | + |
| 16 | +**Example 1:** |
| 17 | + |
| 18 | +**Input:** s = "3[a]2[bc]" |
| 19 | + |
| 20 | +**Output:** "aaabcbc" |
| 21 | + |
| 22 | +**Example 2:** |
| 23 | + |
| 24 | +**Input:** s = "3[a2[c]]" |
| 25 | + |
| 26 | +**Output:** "accaccacc" |
| 27 | + |
| 28 | +**Example 3:** |
| 29 | + |
| 30 | +**Input:** s = "2[abc]3[cd]ef" |
| 31 | + |
| 32 | +**Output:** "abcabccdcdcdef" |
| 33 | + |
| 34 | +**Constraints:** |
| 35 | + |
| 36 | +* `1 <= s.length <= 30` |
| 37 | +* `s` consists of lowercase English letters, digits, and square brackets `'[]'`. |
| 38 | +* `s` is guaranteed to be **a valid** input. |
| 39 | +* All the integers in `s` are in the range `[1, 300]`. |
| 40 | + |
| 41 | +## Solution |
| 42 | + |
| 43 | +```racket |
| 44 | +(define/contract (decode-string s) |
| 45 | + (-> string? string?) |
| 46 | + (let-values ([(result _) (decode-helper (string->list s) 0)]) |
| 47 | + result)) |
| 48 | +
|
| 49 | +(define (decode-helper chars pos) |
| 50 | + (let loop ([current-pos pos] |
| 51 | + [count 0] |
| 52 | + [result ""]) |
| 53 | + (if (>= current-pos (length chars)) |
| 54 | + (values result current-pos) |
| 55 | + (let ([char (list-ref chars current-pos)]) |
| 56 | + (cond |
| 57 | + ; If it's a letter, append it to result |
| 58 | + [(char-alphabetic? char) |
| 59 | + (loop (add1 current-pos) |
| 60 | + count |
| 61 | + (string-append result (string char)))] |
| 62 | + |
| 63 | + ; If it's a digit, update count |
| 64 | + [(char-numeric? char) |
| 65 | + (loop (add1 current-pos) |
| 66 | + (+ (* count 10) (- (char->integer char) (char->integer #\0))) |
| 67 | + result)] |
| 68 | + |
| 69 | + ; If it's '[', handle nested string |
| 70 | + [(char=? char #\[) |
| 71 | + (let-values ([(nested-str new-pos) (decode-helper chars (add1 current-pos))]) |
| 72 | + (loop new-pos |
| 73 | + 0 |
| 74 | + (string-append result |
| 75 | + (string-join |
| 76 | + (make-list count nested-str) |
| 77 | + ""))))] |
| 78 | + |
| 79 | + ; If it's ']', return current result and position |
| 80 | + [(char=? char #\]) |
| 81 | + (values result (add1 current-pos))] |
| 82 | + |
| 83 | + ; Skip other characters |
| 84 | + [else (loop (add1 current-pos) count result)]))))) |
| 85 | +``` |
0 commit comments