Weekly Contest 101的第一道题目,虽然分值才4分,可是倒是中等难度的题目RLE 迭代器:数组
编写一个遍历游程编码序列的迭代器。函数
迭代器由
RLEIterator(int[] A)
初始化,其中A
是某个序列的游程编码。更具体地,对于全部偶数i
,A[i]
告诉咱们在序列中重复非负整数值A[i + 1]
的次数。编码迭代器支持一个函数:
next(int n)
,它耗尽接下来的n
个元素(n >= 1
)并返回以这种方式耗去的最后一个元素。若是没有剩余的元素可供耗尽,则next
返回-1
。指针例如,咱们以
A = [3,8,0,9,2,5]
开始,这是序列 [8,8,8,5,5] 的游程编码。这是由于该序列能够读做 “三个零,零个九,两个五”。code示例:索引
输入:["RLEIterator","next","next","next","next"], [[[3,8,0,9,2,5]],[2],[1],[1],[2]] 输出:[null,8,8,5,-1] 解释: RLEIterator 由 RLEIterator([3,8,0,9,2,5]) 初始化。 这映射到序列 [8,8,8,5,5]。 而后调用 RLEIterator.next 4次。 .next(2) 耗去序列的 2 个项,返回 8。如今剩下的序列是 [8, 5, 5]。 .next(1) 耗去序列的 1 个项,返回 8。如今剩下的序列是 [5, 5]。 .next(1) 耗去序列的 1 个项,返回 5。如今剩下的序列是 [5]。 .next(2) 耗去序列的 2 个项,返回 -1。 这是因为第一个被耗去的项是 5, 但第二个项并不存在。因为最后一个要耗去的项不存在,咱们返回 -1。PS:Leetcode此次的竞赛时间是1小时45分钟是由于竞赛开始了10分钟,可是题目仍是看不到element
其实一开始作这个题目的时候我也是一头雾水,首先游程编码是一个我没接触过的概念,其次是这个题目描述说得太绕了。关于游程编码的概念,能够从网上找到介绍。leetcode
我先从示例入手简单讲解一下题目:get
首先咱们要知道关于初始化的数组实际上是通过游程编码处理后的数组,即压缩后的数组。先展现游程编码先后的数组:it
编码后 [3,8,0,9,2,5] 编码前 [8,8,8,5,5]
根据题目的介绍,对编码后的数组进行处理后:[(3,8),(0,9),(2,5)]
。每一个括号内的其实就是(数字出现次数,对应的数字)
.也就是题目中所说的:
对于全部偶数i
,A[i]
告诉咱们在序列中重复非负整数值A[i + 1]
的次数。
而后咱们能够尝试进行解码:
而题目实际上是要求咱们根据输入的编码后的数组遍历解码(编码前)的数组
/** * RLE 迭代器 * @author RJH * create at 2018/9/9 */ public class RLEIterator { /** * 当前原数据的索引,能够看作是一个指向当前访问位置的指针 */ private int index=0; /** * 当前遍历的元素,对应index+1的原数据的元素。实际上是对应游程编码解压后的元素 */ private int element=-1; /** * 初始化的原数据,实际上是游程编码压缩后的数组 */ private int[] data; public RLEIterator(int[] A) { data=A; } public int next(int n) { while (n>0){ if(index>data.length-2){ element=-1; break; } //当前元素出现次数 int times=data[index]; if(times>0){ if(times>n){ data[index]=times-n; element=data[index+1]; }else{ //表明对应的元素已经遍历完了,因此设为0 data[index]=0; //当前的元素则为index+1的元素 element=data[index+1]; index+=2; } n-=times; }else{ //次数为0,直接访问下一个偶数index对应的次数 index+=2; } } return element; } }