LeetCode 题解工作台

RLE 迭代器

我们可以使用游程编码(即 RLE )来编码一个整数序列。在偶数长度 encoding ( 从 0 开始 )的游程编码数组中,对于所有偶数 i , encoding[i] 告诉我们非负整数 encoding[i + 1] 在序列中重复的次数。 例如,序列 arr = [8,8,8,5,5] 可以被编码…

category

4

题型

code_blocks

5

代码语言

hub

3

相关题

当前训练重点

中等 · 数组·结合·design

bolt

答案摘要

我们定义两个指针 和 ,其中指针 指向当前读取的游程编码,指针 指向当前读取的游程编码中的第几个字符。初始时 $i = 0$, $j = 0$。 每次调用 `next(n)` 时,我们判断当前游程编码中剩余的字符数 $encoding[i] - j$ 是否小于 ,若是,则将 减去 $encoding[i] - j$,并将 加 , 置为 ,然后继续判断下一个游程编码;若不是,则将 加 ,…

Interview AiBox logo

Interview AiBox 实时 AI 助手,陪你讲清 数组·结合·design 题型思路

试试 AiBox 面试助手arrow_forward
description

题目描述

我们可以使用游程编码(即 RLE )来编码一个整数序列。在偶数长度 encoding ( 从 0 开始 )的游程编码数组中,对于所有偶数 iencoding[i] 告诉我们非负整数 encoding[i + 1] 在序列中重复的次数。

  • 例如,序列 arr = [8,8,8,5,5] 可以被编码为 encoding =[3,8,2,5]encoding =[3,8,0,9,2,5] 和 encoding =[2,8,1,8,2,5] 也是 arr 有效的 RLE

给定一个游程长度的编码数组,设计一个迭代器来遍历它。

实现 RLEIterator 类:

  • RLEIterator(int[] encoded) 用编码后的数组初始化对象。
  • int next(int n) 以这种方式耗尽后 n 个元素并返回最后一个耗尽的元素。如果没有剩余的元素要耗尽,则返回 -1

 

示例 1:

输入:
["RLEIterator","next","next","next","next"]
[[[3,8,0,9,2,5]],[2],[1],[1],[2]]
输出:
[null,8,8,5,-1]
解释:
RLEIterator rLEIterator = new RLEIterator([3, 8, 0, 9, 2, 5]); // 这映射到序列 [8,8,8,5,5]。
rLEIterator.next(2); // 耗去序列的 2 个项,返回 8。现在剩下的序列是 [8, 5, 5]。
rLEIterator.next(1); // 耗去序列的 1 个项,返回 8。现在剩下的序列是 [5, 5]。
rLEIterator.next(1); // 耗去序列的 1 个项,返回 5。现在剩下的序列是 [5]。
rLEIterator.next(2); // 耗去序列的 2 个项,返回 -1。 这是由于第一个被耗去的项是 5,
但第二个项并不存在。由于最后一个要耗去的项不存在,我们返回 -1。

 

提示:

  • 2 <= encoding.length <= 1000
  • encoding.length 为偶
  • 0 <= encoding[i] <= 109
  • 1 <= n <= 109
  • 每个测试用例调用next 不高于 1000 次 
lightbulb

解题思路

方法一:维护两个指针

我们定义两个指针 iijj,其中指针 ii 指向当前读取的游程编码,指针 jj 指向当前读取的游程编码中的第几个字符。初始时 i=0i = 0, j=0j = 0

每次调用 next(n) 时,我们判断当前游程编码中剩余的字符数 encoding[i]jencoding[i] - j 是否小于 nn,若是,则将 nn 减去 encoding[i]jencoding[i] - j,并将 ii22jj 置为 00,然后继续判断下一个游程编码;若不是,则将 jjnn,并返回 encoding[i+1]encoding[i + 1]

ii 超出了游程编码的长度,依然没有返回值,则说明没有剩余的元素要耗尽,返回 1-1

时间复杂度 O(n+q)O(n + q),空间复杂度 O(n)O(n)。其中 nn 是游程编码的长度,而 qq 是调用 next(n) 的次数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class RLEIterator:
    def __init__(self, encoding: List[int]):
        self.encoding = encoding
        self.i = 0
        self.j = 0

    def next(self, n: int) -> int:
        while self.i < len(self.encoding):
            if self.encoding[self.i] - self.j < n:
                n -= self.encoding[self.i] - self.j
                self.i += 2
                self.j = 0
            else:
                self.j += n
                return self.encoding[self.i + 1]
        return -1


# Your RLEIterator object will be instantiated and called as such:
# obj = RLEIterator(encoding)
# param_1 = obj.next(n)
speed

复杂度分析

指标
时间complexity is O(k) per call to next, where k is the number of encoding segments traversed; space complexity is O(1) since the iterator uses the original encoding without expansion.
空间Depends on the final approach
psychology

面试官常问的追问

外企场景
  • question_mark

    Expecting in-place iteration without full sequence expansion.

  • question_mark

    Watch for off-by-one errors in large counts.

  • question_mark

    Check handling of next(n) when n exceeds remaining elements.

warning

常见陷阱

外企场景
  • error

    Trying to expand the full sequence causing memory issues.

  • error

    Failing to update the pointer correctly after exhausting counts.

  • error

    Returning incorrect values when next(n) exceeds remaining elements.

swap_horiz

进阶变体

外企场景
  • arrow_right_alt

    Implement a peek() method to see the next element without consuming it.

  • arrow_right_alt

    Support decrementing elements from the sequence dynamically.

  • arrow_right_alt

    Adapt the iterator for multiple simultaneous sequences with independent pointers.

help

常见问题

外企场景

RLE 迭代器题解:数组·结合·design | LeetCode #900 中等