> ## Documentation Index
> Fetch the complete documentation index at: https://leetcode-py.wisl.dev/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> leetcode-py is a Python LeetCode practice environment generator with one CLI: lcpy. It is not a service or platform.
> Each problem is a directory under leetcode/ with README.md, solution.py, test_solution.py, helpers.py, and playground.ipynb. lcpy gen creates them from JSON templates bundled with the package.
> Examples are backed by tests; copy them verbatim.

# Design Compressed String Iterator

> Tested Python solution for LeetCode 604 with 12 pytest cases. Generate a practice environment with lcpy.

LeetCode 604, [Easy](/catalog/easy). Topics: [Design](/catalog/topics/design), [Array](/catalog/topics/array), [String](/catalog/topics/string), Iterator. [View on LeetCode](https://leetcode.com/problems/design-compressed-string-iterator/description/).

Generate this problem as a practice environment: tested reference solution, 12 [parametrized pytest cases](/practice/testing), and a playground notebook:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 604   # by problem number
lcpy gen -s design_compressed_string_iterator   # by problem name
```

## Problem

Design and implement a data structure for a compressed string iterator. The given compressed string will be in the form of each letter followed by a positive integer representing the number of this letter existing in the original uncompressed string.

Implement the `StringIterator` class:

* `next()` Returns **the next character** if the original string still has uncompressed characters, otherwise returns a **white space**.
* `has_next()` Returns true if there is any letter needs to be uncompressed in the original string, otherwise returns `false`.

### Examples

```
Input
["StringIterator", "next", "next", "next", "next", "next", "next", "hasNext", "next", "hasNext"]
[["L1e2t1C1o1d1e1"], [], [], [], [], [], [], [], [], []]
Output
[null, "L", "e", "e", "t", "C", "o", true, "d", true]

Explanation
StringIterator stringIterator = new StringIterator("L1e2t1C1o1d1e1");
stringIterator.next(); // return "L"
stringIterator.next(); // return "e"
stringIterator.next(); // return "e"
stringIterator.next(); // return "t"
stringIterator.next(); // return "C"
stringIterator.next(); // return "o"
stringIterator.hasNext(); // return True
stringIterator.next(); // return "d"
stringIterator.hasNext(); // return True
```

### Constraints

* `1 <= compressedString.length <= 1000`
* `compressedString` consists of lower-case an upper-case English letters and digits.
* The number of a single character repetitions in `compressedString` is in the range `[1, 10^9]`.
* At most `100` calls will be made to `next` and `hasNext`.

## Solution

Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/design_compressed_string_iterator/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/design_compressed_string_iterator/test_solution.py):

```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class StringIterator:
    # Time: next/has_next O(1) amortized
    # Space: O(k) for k letter-count pairs
    def __init__(self, compressed_string: str) -> None:
        self.pairs: list[tuple[str, int]] = []
        i = 0
        while i < len(compressed_string):
            ch = compressed_string[i]
            i += 1
            num = 0
            while i < len(compressed_string) and compressed_string[i].isdigit():
                num = num * 10 + int(compressed_string[i])
                i += 1
            self.pairs.append((ch, num))
        self.idx = 0

    def next(self) -> str:
        if self.idx >= len(self.pairs):
            return " "
        ch = self.pairs[self.idx][0]
        ch, count = self.pairs[self.idx]
        if count == 1:
            self.idx += 1
        else:
            self.pairs[self.idx] = (ch, count - 1)
        return ch

    def has_next(self) -> bool:
        return self.idx < len(self.pairs)
```

## Complexity

| Time | Space |
| - | - |
| next/has\_next O(1) amortized | O(k) for k letter-count pairs |

## Tags

[NeetCode All](/catalog/neetcode).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.