本题的难点是,这不是一个双重数组,数组里面是一个NestedInteger类,它有isInteger, getInteger, getList等方法。因此很容易被示例中的 [[1,1],2,[1,1]]
所误导。
class NestedIterator {
constructor(nestedList) {
this.s = nestedList
}
next() {
var el = this.s.shift()
return el.getInteger()
}
hasNext() {
var s = this.s
while (s.length) {
var temp = s[0]
if (temp.isInteger()) {
return true;
}
s.shift();
//如果temp为一个数组
for (var i = temp.getList().length - 1; i >= 0; i--) {
s.unshift(temp.getList()[i]);
}
}
return false;
}
}
如果传参真的是一个 [[1,1],2,[1,1]]
数组又如何呢,并且它支持如下两种遍历。
//遍历1
var i = new NestedIterator([[1, 2, 2.5], [], 3, [4, 5]]), a = [];
do {
var val = i.next();
if (typeof val == 'number') {
a.push(val)
} else {
break
}
} while (true)
console.log(a)
======
//遍历2
var i = new NestedIterator([[1, 2, 2.5], [], 3, [4, 5]]), a = [];
while (i.hasNext()) a.push(i.next());
console.log(a)
这时我们需要引进一个变量,让它无论如何 都走一下hasNext方法
class NestedIterator {
constructor(list) {
this.s = list
this._hasCallHasNext = false;
}
next() {
if (!this._hasCallHasNext) {
this.hasNext()
}
var el = this.s.shift()
this._hasCallHasNext = false;
return el
}
hasNext() {
var s = this.s
while (s.length) {
var temp = s[0]
if (typeof temp === 'number') {
this._hasCallHasNext = true;
return true;
}
s.shift();
//如果temp为一个数组
for (var i = temp.length - 1; i >= 0; i--) {
s.unshift(temp[i]);
}
}
return false;
}
}
但这会改变数组的结构,更普适的方案是添加两个游标:
class NestedIterator {
constructor(list) {
this.s = list
this.I = 0;
this.J = 0;
this._hasCallHasNext = false;
}
next() {
if (!this._hasCallHasNext) {
this.hasNext()
}
var list = this.s[this.I], val
if (Array.isArray(list)) {
val = list[this.J]
this.J++;
} else {
val = list;
this.I++
this.J = 0;
}
this._hasCallHasNext = false
return val
}
hasNext() {
var s = this.s;
for (var i = this.I; i < s.length; i++) {
var temp = s[i]
if (typeof temp === 'number') {
this.I = i
this._hasCallHasNext = true;
return true;
}
if (this.J > temp.length) {
this.J = 0;
}
for (var j = this.J; j < temp.length; j++) {
var el = temp[j]
if (typeof el === 'number') {
this.J = j
this._hasCallHasNext = true;
return true;
}
}
}
return false
}
}