604. Design Compressed String Iterator
Разработайте и реализуйте структуру данных для итератора сжатой строки. Данная сжатая строка будет в виде каждой буквы, за которой следует положительное целое число, представляющее количество этой буквы в оригинальной несжатой строке.
Реализуйте класс
StringIterator
-
next()
: Возвращает следующий символ, если в оригинальной строке еще остались несжатые символы, в противном случае возвращает пробел.
-
hasNext()
: Возвращает
true
, если в оригинальной строке остались символы, которые нужно распаковать, в противном случае возвращает
false
.
Пример:
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
C# решение
сопоставлено/оригиналpublic class StringIterator {
private StringBuilder res = new StringBuilder();
private int ptr = 0;
public StringIterator(string s) {
int i = 0;
while (i < s.Length) {
char ch = s[i++];
int num = 0;
while (i < s.Length && char.IsDigit(s[i])) {
num = num * 10 + (s[i] - '0');
i++;
}
for (int j = 0; j < num; j++)
res.Append(ch);
}
}
public char Next() {
return !HasNext() ? ' ' : res[ptr++];
}
public bool HasNext() {
return ptr != res.Length;
}
}
C++ решение
auto-draft, проверить перед отправкой#include <bits/stdc++.h>
using namespace std;
// Auto-generated C++ draft from the C# solution. Review containers, LINQ and helper types before submit.
public class StringIterator {
private StringBuilder res = new StringBuilder();
private int ptr = 0;
public StringIterator(string s) {
int i = 0;
while (i < s.size()) {
char ch = s[i++];
int num = 0;
while (i < s.size() && char.IsDigit(s[i])) {
num = num * 10 + (s[i] - '0');
i++;
}
for (int j = 0; j < num; j++)
res.Append(ch);
}
}
public char Next() {
return !HasNext() ? ' ' : res[ptr++];
}
public bool HasNext() {
return ptr != res.size();
}
}
Java решение
сопоставлено/оригиналpublic class StringIterator {
StringBuilder res = new StringBuilder();
int ptr = 0;
public StringIterator(String s) {
int i = 0;
while (i < s.length()) {
char ch = s.charAt(i++);
int num = 0;
while (i < s.length() && Character.isDigit(s.charAt(i))) {
num = num * 10 + s.charAt(i) - '0';
i++;
}
for (int j = 0; j < num; j++)
res.append(ch);
}
}
public char next() {
return !hasNext() ? ' ' : res.charAt(ptr++);
}
public boolean hasNext() {
return ptr != res.length();
}
}
JavaScript решение
сопоставлено/оригиналclass StringIterator {
constructor(s) {
this.res = [];
this.ptr = 0;
let i = 0;
while (i < s.length) {
let ch = s[i++];
let num = 0;
while (i < s.length && !isNaN(s[i])) {
num = num * 10 + parseInt(s[i]);
i++;
}
this.res.push(...Array(num).fill(ch));
}
}
next() {
return this.hasNext() ? this.res[this.ptr++] : ' ';
}
hasNext() {
return this.ptr < this.res.length;
}
}
Python решение
сопоставлено/оригиналclass StringIterator:
def __init__(self, s: str):
self.res = []
self.ptr = 0
i = 0
while i < len(s):
ch = s[i]
i += 1
num = 0
while i < len(s) and s[i].isdigit():
num = num * 10 + int(s[i])
i += 1
self.res.extend([ch] * num)
def next(self) -> str:
if not self.hasNext():
return ' '
char = self.res[self.ptr]
self.ptr += 1
return char
def hasNext(self) -> bool:
return self.ptr < len(self.res)
Go решение
сопоставлено/оригиналpackage main
type StringIterator struct {
res []rune
ptr int
}
func Constructor(s string) StringIterator {
res := []rune{}
i := 0
for i < len(s) {
ch := rune(s[i])
i++
num := 0
for i < len(s) && s[i] >= '0' && s[i] <= '9' {
num = num*10 + int(s[i]-'0')
i++
}
for j := 0; j < num; j++ {
res = append(res, ch)
}
}
return StringIterator{res: res, ptr: 0}
}
func (this *StringIterator) Next() rune {
if !this.HasNext() {
return ' '
}
ch := this.res[this.ptr]
this.ptr++
return ch
}
func (this *StringIterator) HasNext() bool {
return this.ptr < len(this.res)
}
Algorithm
Предварительная обработка
Мы заранее создаем несжатую строку. Для этого проходим по данному сжатому строковому представлению и добавляем несжатые буквы для каждой сжатой буквы в результирующий строковый строитель res. Чтобы найти количество несжатых букв, мы проходим по данному сжатому строковому представлению. Когда находим букву, определяем следующее за ней число, используя десятичную арифметику. Таким образом, получаем два элемента (букву и количество), необходимые для формирования текущего фрагмента несжатой строки.
Операция next()
Начинаем с проверки, есть ли еще несжатые буквы в строке. Если нет, hasNext() возвращает False, а next() возвращает пробел (' '). В противном случае возвращаем букву, на которую указывает ptr, указывающий на следующую букву для возврата. Перед возвратом буквы также обновляем ptr, чтобы указывать на следующую букву в res.
Операция hasNext()
Если указатель ptr выходит за пределы массива res, это указывает на то, что больше несжатых букв нет. В этом случае возвращаем False. В противном случае возвращаем True.
😎
Вакансии для этой задачи
Показаны активные вакансии с пересечением по тегам задачи.