本题LeetCode链接:
https://leetcode-cn.com/problems/flatten-nested-list-iterator/
本题简单来说,就是对于一个多层嵌套的列表,按顺序输出里面的每一个内容,例如:
输入: [1,[4,[6]]] 输出: [1,4,6]
如果只是单纯地进行输出,那么可以很简单使用递归:
def fun(data):
for i in data:
if isinstance(i,int):
print(i)
else:
fun(i)
data = [1,[4,[6]]]
fun(data)
针对列表的每一项,如果是整数,就直接输出,如果是列表,就递归。
评论区一位同学说得很好:
LeetCode上面的题目,对输出的要求进行了修改,要求以迭代器的形式输出,即:可以调用函数hasNext()判断是否有下一个元素,调用函数next()输出下一个元素。
那么本题有两个方法,第一种方法,就是在构造迭代器的时候,就使用上述递归方法,将每个元素都入队列,之后hasNext()判断队列是否为空即可,next()输出队列头即可。
带示例代码如下:
class KNode:
def __init__(self,data) -> None:
self.data = data
def isInt(self) -> bool:
"""
@return bool
"""
return isinstance(self.data,int)
def getInt(self) -> int:
"""
@return the single Int that this KNode holds
"""
return self.data
def getList(self) :
"""
@return the KNode list
"""
return self.data
class KNodeIterator:
def fun(self,data):
for i in data:
if i.isInt():
self.queue.append(i)
else:
self.fun(i.getList())
def __init__(self, KNodeList):
"""
可以知道,这个地方的时间复杂度为O(N)
"""
self.queue = []
self.fun(KNodeList)
def next(self) -> int:
"""
要求O(1)
"""
cur = self.queue.pop(0)
return cur.getInt()
def hasNext(self) -> bool:
"""
时间复杂度O(1)
"""
if self.queue:
return True
else:
return False
a1 = KNode(1)
a2 = KNode(2)
a3 = KNode(3)
a4 = KNode(4)
a5 = KNode(5)
# kNodes = [5,[4],[3,[]],[2,1]]
kNodes = [KNode(5),KNode([KNode(4)]),KNode([KNode(3),KNode([])]),KNode([KNode(2),KNode(1)])]
iter = KNodeIterator(kNodes)
while iter.hasNext():
# visit iter.next()
print(iter.next())
但其实这个方法并不符合迭代器的思想,迭代器不应该在构造的时候,就将最终要输出的数据整理完毕,进行存储。也就是说,在构造函数中,时间复杂度应该为1,在hasNext的时候,再进行数据的整理。
在这里,我们将初始状态列表所有内容入栈,在hasNext的时候,判断栈顶是否为空,是否为整数,是否为列表。
如果是空,那么没有后续
如果是整数,那么有后续
如果是列表(列表可能为空),需要将列表中拆开,将里面的内容重新入栈。
即,对于样例:[1,[4,[6]]]
- 初始栈为:[1,[4,[6]]] 注:python的列表可以很方便进行最左侧操作,因此这里的栈的形式,和一般的栈的形式是反过来的。
- 将1出栈,栈为:[ [4,[6]] ]
- 将[4,[6]]拆解为4和[6],重新入栈,注意入栈顺序。入栈后,栈为:[4,[6]]
- 将4出栈,栈为:[[6]]
- 将[6]拆解为 6 ,重新入栈。入栈后,栈为:[6]
- 将6出栈,栈为:[ ]
- 栈空,无后续元素。
样例代码如下:
class KNode:
def __init__(self,data) -> None:
self.data = data
def isInt(self) -> bool:
"""
@return bool
"""
return isinstance(self.data,int)
def getInt(self) -> int:
"""
@return the single Int that this KNode holds
"""
return self.data
def getList(self) :
"""
@return the KNode list
"""
return self.data
class KNodeIterator:
def __init__(self, KNodeList):
"""
时间复杂度为O(1)
对于python来说,这个地方其实是一个列表的引用
也就是说,后续对nodelist的操作,其实都是直接在kNodeList上的
"""
self.nodelist = KNodeList
def next(self) -> int:
"""
要求O(1)
"""
cur = self.nodelist.pop(0)
return cur.getInt()
def hasNext(self) -> bool:
"""
一般时间复杂度O(1),最坏时间复杂度为O(N)
"""
while self.nodelist:
if self.nodelist[0].isInt():
return True
else:
t = self.nodelist[0].getList()
self.nodelist.pop(0)
for i in range(len(t)-1,-1,-1):
self.nodelist.insert(0,t[i])
return False
a1 = KNode(1)
a2 = KNode(2)
a3 = KNode(3)
a4 = KNode(4)
a5 = KNode(5)
# kNodes = [5,[4],[3,[]],[2,1]]
kNodes = [KNode(5),KNode([KNode(4)]),KNode([KNode(3),KNode([])]),KNode([KNode(2),KNode(1)])]
print(kNodes)
iter = KNodeIterator(kNodes)
while iter.hasNext():
# visit iter.next()
print(iter.next())
print(kNodes)
参考链接: