返回介绍

solution / 0600-0699 / 0604.Design Compressed String Iterator / README

发布于 2024-06-17 01:03:36 字数 5989 浏览 0 评论 0 收藏 0

604. 迭代压缩字符串

English Version

题目描述

设计并实现一个迭代压缩字符串的数据结构。给定的压缩字符串的形式是,每个字母后面紧跟一个正整数,表示该字母在原始未压缩字符串中出现的次数。

设计一个数据结构,它支持如下两种操作: next 和 hasNext

  • next() - 如果原始字符串中仍有未压缩字符,则返回下一个字符,否则返回空格
  • hasNext() - 如果原始字符串中存在未压缩的的字母,则返回true,否则返回false

 

示例 1:

输入:
["StringIterator", "next", "next", "next", "next", "next", "next", "hasNext", "next", "hasNext"]
[["L1e2t1C1o1d1e1"], [], [], [], [], [], [], [], [], []]
输出:
[null, "L", "e", "e", "t", "C", "o", true, "d", true]

解释:
StringIterator stringIterator = new StringIterator("L1e2t1C1o1d1e1");
stringIterator.next(); // 返回 "L"
stringIterator.next(); // 返回 "e"
stringIterator.next(); // 返回 "e"
stringIterator.next(); // 返回 "t"
stringIterator.next(); // 返回 "C"
stringIterator.next(); // 返回 "o"
stringIterator.hasNext(); // 返回 True
stringIterator.next(); // 返回 "d"
stringIterator.hasNext(); // 返回 True

 

提示:

  • 1 <= compressedString.length <= 1000
  • compressedString 由小写字母、大写字母和数字组成。
  • 在 compressedString 中,单个字符的重复次数在 [1,10 ^9] 范围内。
  • next 和 hasNext 的操作数最多为 100 。

解法

方法一:解析存储

compressedString 解析成字符 $c$ 和对应的重复次数 $x$,存储在数组或列表 $d$ 中,用 $p$ 指向当前字符。

然后在 nexthasNext 中进行操作。

初始化的时间复杂度为 $O(n)$,其余操作的时间复杂度为 $O(1)$。其中 $n$ 为 compressedString 的长度。

class StringIterator:
  def __init__(self, compressedString: str):
    self.d = []
    self.p = 0
    n = len(compressedString)
    i = 0
    while i < n:
      c = compressedString[i]
      x = 0
      i += 1
      while i < n and compressedString[i].isdigit():
        x = x * 10 + int(compressedString[i])
        i += 1
      self.d.append([c, x])

  def next(self) -> str:
    if not self.hasNext():
      return ' '
    ans = self.d[self.p][0]
    self.d[self.p][1] -= 1
    if self.d[self.p][1] == 0:
      self.p += 1
    return ans

  def hasNext(self) -> bool:
    return self.p < len(self.d) and self.d[self.p][1] > 0


# Your StringIterator object will be instantiated and called as such:
# obj = StringIterator(compressedString)
# param_1 = obj.next()
# param_2 = obj.hasNext()
class StringIterator {
  private List<Node> d = new ArrayList<>();
  private int p;

  public StringIterator(String compressedString) {
    int n = compressedString.length();
    int i = 0;
    while (i < n) {
      char c = compressedString.charAt(i);
      int x = 0;
      while (++i < n && Character.isDigit(compressedString.charAt(i))) {
        x = x * 10 + (compressedString.charAt(i) - '0');
      }
      d.add(new Node(c, x));
    }
  }

  public char next() {
    if (!hasNext()) {
      return ' ';
    }
    char ans = d.get(p).c;
    if (--d.get(p).x == 0) {
      ++p;
    }
    return ans;
  }

  public boolean hasNext() {
    return p < d.size() && d.get(p).x > 0;
  }
}

class Node {
  char c;
  int x;

  Node(char c, int x) {
    this.c = c;
    this.x = x;
  }
}

/**
 * Your StringIterator object will be instantiated and called as such:
 * StringIterator obj = new StringIterator(compressedString);
 * char param_1 = obj.next();
 * boolean param_2 = obj.hasNext();
 */
class StringIterator {
public:
  StringIterator(string compressedString) {
    int n = compressedString.size();
    int i = 0;
    while (i < n) {
      char c = compressedString[i];
      int x = 0;
      while (++i < n && isdigit(compressedString[i])) {
        x = x * 10 + (compressedString[i] - '0');
      }
      d.push_back({c, x});
    }
  }

  char next() {
    if (!hasNext()) return ' ';
    char ans = d[p].first;
    if (--d[p].second == 0) {
      ++p;
    }
    return ans;
  }

  bool hasNext() {
    return p < d.size() && d[p].second > 0;
  }

private:
  vector<pair<char, int>> d;
  int p = 0;
};

/**
 * Your StringIterator object will be instantiated and called as such:
 * StringIterator* obj = new StringIterator(compressedString);
 * char param_1 = obj->next();
 * bool param_2 = obj->hasNext();
 */
type pair struct {
  c byte
  x int
}

type StringIterator struct {
  d []pair
  p int
}

func Constructor(compressedString string) StringIterator {
  n := len(compressedString)
  i := 0
  d := []pair{}
  for i < n {
    c := compressedString[i]
    x := 0
    i++
    for i < n && compressedString[i] >= '0' && compressedString[i] <= '9' {
      x = x*10 + int(compressedString[i]-'0')
      i++
    }
    d = append(d, pair{c, x})
  }
  return StringIterator{d, 0}
}

func (this *StringIterator) Next() byte {
  if !this.HasNext() {
    return ' '
  }
  ans := this.d[this.p].c
  this.d[this.p].x--
  if this.d[this.p].x == 0 {
    this.p++
  }
  return ans
}

func (this *StringIterator) HasNext() bool {
  return this.p < len(this.d) && this.d[this.p].x > 0
}

/**
 * Your StringIterator object will be instantiated and called as such:
 * obj := Constructor(compressedString);
 * param_1 := obj.Next();
 * param_2 := obj.HasNext();
 */

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文