This problem requires designing a StringIterator
class that iterates through a compressed string. The compressed string format is character + count
, for example, "L1e2t1C1o1d1e1" represents "LeeetCode". The class needs to implement two methods: next()
, which returns the next character in the uncompressed string, and hasNext()
, which checks if there are more characters to be processed.
The core idea is to preprocess the compressed string into a more convenient data structure. We can create a list of pairs, where each pair contains a character and its count. This way, next()
becomes simply decrementing the count for the current pair and advancing to the next if the count reaches zero. hasNext()
checks if there is any pair with a count greater than zero.
__init__(self, compressedString: str)
: The constructor iterates through the compressed string once. The time complexity is O(m), where m is the length of the compressed string.next(self) -> str
: This operation has a time complexity of O(1) because it only involves accessing and updating the count of the current character.hasNext(self) -> bool
: Similar to next()
, this method takes O(1) time.Therefore, the overall time complexity is dominated by the constructor, making it O(m).
The space complexity is O(n), where n is the number of unique characters in the compressed string. This is because we store the pairs of characters and their counts in a list. In the worst case, each character could be unique, resulting in a space complexity proportional to n.
The Python code implements the approach as follows:
Constructor (__init__
):
d
to store character-count pairs.compressedString
, extracting characters and their counts.(character, count)
pair to the d
list.next()
:
hasNext()
. If not, it returns a space.hasNext()
:
p
is within the bounds of d
and if the current pair's count is greater than 0.The other languages (Java, C++, Go) follow a similar structure, only differing in syntax and data structure usage. For instance, Java uses a Node
class to encapsulate the character-count pair and ArrayList
to manage the list of pairs, while C++ leverages std::vector<std::pair<char, int>>
for the same purpose. Go employs a custom pair
struct and slices. However, the algorithmic logic remains consistent across all implementations.