持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第5天,点击查看活动详情
给你一个嵌套的整数列表 nestedList 。每个元素要么是一个整数,要么是一个列表;该列表的元素也可能是整数或者是其他列表。请你实现一个迭代器将其扁平化,使之能够遍历这个列表中的所有整数。
实现扁平迭代器类 NestedIterator :
- NestedIterator(List nestedList) 用嵌套列表 nestedList 初始化迭代器。
- int next() 返回嵌套列表的下一个整数。
- boolean hasNext() 如果仍然存在待迭代的整数,返回 true ;否则,返回 false 。
你的代码将会用下述伪代码检测:
initialize iterator with nestedList
res = []
while iterator.hasNext()
append iterator.next() to the end of res
return res
如果 res 与预期的扁平化列表匹配,那么你的代码将会被判为正确。
方案1:栈
-
让原始数组倒序入栈:[1,2,3,[4,5],6] => [6, [4, 5], 3, 2, 1]
-
每次出栈,判断是否是单个元素
-
如果是单个元素则直接出栈
-
否则其就是一个数组,将其出栈后拆开,再对拆开的元素依次倒序入栈
-
假设目前已经出了 1,2,3 三个元素,正在出
[4, 5]- 当前栈:[6, [4, 5]]
- 弹出栈顶元素后,当前栈:[6],弹出的元素 [4, 5]
- 发现弹出的元素是一个数组,则将其依次倒序入栈后,当前栈:[6, 5, 4]
- 继续出栈操作,知道栈为空
-
function reverseInsert(result, list) { // 逆序插入元素
result.push(...list.reverse())
}
/**
* @constructor
* @param {NestedInteger[]} nestedList
*/
var NestedIterator = function(nestedList) {
// 注意,题目说明了传入的是一个 NestedInteger 的数组,NestedInteger是一个实例,上面有 isInteger 、 getInteger 和 getList 三个方法
this.stack = []
reverseInsert(this.stack, nestedList)
}
NestedIterator.prototype.stackTop2Integer = function() {
while(this.stack.length > 0) { // 持续循环到栈为空,或者栈顶元素不是数组
const top = this.stack[this.stack.length - 1] // 获取栈顶元素
if(top.isInteger()) return // 如果栈顶元素是 Integer 类型,则结束循环
// 走到这里,说明栈顶元素是一个数组
this.stack.pop() // 删除栈顶元素
const list = top.getList() // 如果 NestedInteger 是一个嵌套数组,则 getList 返回这个链表数组
reverseInsert(this.stack, list) // 将其倒序插入栈中
}
}
NestedIterator.prototype.next = function() {
this.stackTop2Integer() // 调整栈顶元素,调整过后栈顶元素一定是单值,或者为空
const top = this.stack.pop()
return top.getInteger()
}
NestedIterator.prototype.hasNext = function() {
this.stackTop2Integer()
return this.stack.length > 0
}
方法2:递归
在栈的解法中,我们是等到每次调用 next 才调整一次栈顶
换个思路的话,在初始化的时候直接用递归构建好展平后的数组,等待 next 来取
var NestedIterator = function (nestedList) {
this.nums = []
this.index = 0
for(let nestedInterger of nestedList) {
this.nums.push(...dfs(nestedInterger))
}
};
function dfs(nestedInterger) {
const res = []
if(nestedInterger.isInteger()) {
res.push(nestedInterger.getInteger())
} else {
for(let child of nestedInterger.getList()) {
res.push(...dfs(child))
}
}
return res
}
NestedIterator.prototype.hasNext = function () {
return this.index < this.nums.length;
};
NestedIterator.prototype.next = function () {
return this.nums[this.index++];
};
\