LeetCode Everyday - RLE 迭代器

201 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第2天,点击查看活动详情 >>

RLE 迭代器

我们可以使用游程编码(即 RLE )来编码一个整数序列。在偶数长度 encoding ( 从 0 开始 )的游程编码数组中,对于所有偶数 i ,encoding[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 次 

解题思路:

答案分为两部分, 首先是构造函数, 由于直接生成数组会造成栈溢出, 所以我选择将数组转换成对象来存储每个数字(第i+1个元素)出现的次数(第i个元素), 然后放到构造函数的value中, 第二个是原型链上的next方法,  思路是先判断n是否大于value对象所有次数之和, 是则直接将对象置空, 返回-1, 否则遍历对象, 判断n如果大于当前值, 就把n减去当前值, 然后删掉该元素, 直到n小于或等于当前值时, 将当前值减去n, 然后返回当前值。

我的答案:

/**
 * @param {number[]} encoding
 */
var RLEIterator = function(encoding) {
    // 一个数组保存值的数量, 一个数组保存值
    let countAry = []
    let valAry = []
    for(let i = 0; i< encoding.length; i += 2) {
        if (encoding[i] > 0) {
            countAry.push(encoding[i])
            valAry.push(encoding[i + 1])
        }
    }
    this.resObj = {countAry, valAry}
};

/** 
 * @param {number} n
 * @return {number}
 */
RLEIterator.prototype.next = function(n) {
    let ret = -1
    // 如果入参n大于当前值数量数组第一个元素时, 就删除该元素以及值数组对应元素, 否则中段循环, 将对应值返回
    while(n && this.resObj.countAry.length) {
        if (n > this.resObj.countAry[0]) {
            n -= this.resObj.countAry[0]
            this.resObj.countAry.splice(0, 1)
            this.resObj.valAry.splice(0, 1)
        } else {
            this.resObj.countAry[0] -= n
            n = 0
            ret = this.resObj.valAry.length ?  this.resObj.valAry[0] : -1
        }
    }

    return ret
};

最后

如果有更好的解法或者思路, 欢迎在评论区和我交流~ ღ( ´・ᴗ・` )