python扁平化界面_341. 扁平化嵌套列表迭代器(Python)

题目

难度:★★★☆☆

类型:数组

方法:动态规划

给你一个嵌套的整型列表。请你设计一个迭代器,使其能够遍历这个整型列表中的所有整数。

列表中的每一项或者为一个整数,或者是另一个列表。其中列表的元素也可能是整数或是其他列表。

示例

示例 1:

输入: [[1,1],2,[1,1]]

输出: [1,1,2,1,1]

解释: 通过重复调用 next 直到 hasNext 返回 false,next 返回的元素的顺序应该是: [1,1,2,1,1]。

示例 2:

输入: [1,[4,[6]]]

输出: [1,4,6]

解释: 通过重复调用 next 直到 hasNext 返回 false,next 返回的元素的顺序应该是: [1,4,6]。

解答

首先,有必要给出这个嵌套列表跟我们平常所用的有什么不同,需要给出详细的构造代码。首先是结点,结点的值可以是整数也可以是列表,具有获取整数和获取列表两个方法。

class NestedInteger:

def __init__(self, value):

self.value = value

def isInteger(self) -> bool:

"""

@return True if this NestedInteger holds a single integer, rather than a nested list.

"""

return isinstance(self.value, int)

def getInteger(self) -> int:

"""

@return the single integer that this NestedInteger holds, if it holds a single integer

Return None if this NestedInteger holds a nested list

"""

assert isinstance(self.value, int)

return self.value

def getList(self):

"""

@return the nested list that this NestedInteger holds, if it holds a nested list

Return None if this NestedInteger holds a single integer

"""

assert isinstance(self.value, list)

return self.value

然后是构造嵌套列表,这里使用深度优先搜索实现:

def create_nested_list(l):

"""

构造一个嵌套列表。

:param l:

:return:

"""

res_lst = []

for item in l:

if isinstance(item, int):

res_lst.append(NestedInteger(item))

elif isinstance(item, list):

res_lst.append(create_nested_list(item))

return NestedInteger(res_lst)

我们用类似的方法实现嵌套链表的解压,和构造过程是逆过程。

def flatten_nested_list(lst):

"""

将嵌套列表扁平化。

:param lst:

:return:

"""

res = []

def dfs(l):

if isinstance(l, NestedInteger):

l = l.getInteger() if l.isInteger() else l.getList()

for item in l:

assert isinstance(item, NestedInteger)

if item.isInteger():

res.append(item.getInteger())

else:

dfs(item.getList())

dfs(lst)

return res

然后就可以解决问题了。

方法1:直接解压嵌套列表

将嵌套列表解压,用指针来标记当前位置。这个思路很简洁。

class NestedIterator:

"""

嵌套列表迭代器

"""

def __init__(self, nestedList):

self.flat_list = flatten_nested_list(nestedList)

self.point = 0

self.length = len(self.flat_list)

def next(self) -> int:

self.point += 1

return self.flat_list[self.point-1]

def hasNext(self) -> bool:

return self.point < self.length

方法2:堆栈

参考大佬解决方案。

class NestedIterator:

def __init__(self, nestedList: [NestedInteger]):

# 对于nestedList中的内容,我们需要从左往右遍历,

# 但堆栈pop是从右端开始,所以我们压栈的时候需要将nestedList反转再压栈

self.stack = nestedList[::-1]

def next(self) -> int:

# hasNext 函数中已经保证栈顶是integer,所以直接返回pop结果

return self.stack.pop(-1).getInteger()

def hasNext(self) -> bool:

# 对栈顶进行‘剥皮’,如果栈顶是List,把List反转再依次压栈,

# 然后再看栈顶,依次循环直到栈顶为Integer。

# 同时可以处理空的List,类似[[[]],[]]这种test case

while len(self.stack) > 0 and self.stack[-1].isInteger() is False:

self.stack += self.stack.pop().getList()[::-1]

return len(self.stack) > 0

方法3:生成器

充分利用python的作用,用生成器构造。

class NestedIterator(object):

def __init__(self, nestedList):

"""

Initialize your data structure here.

:type nestedList: List[NestedInteger]

"""

def build_generator(nestedList):

for i in nestedList:

if i.isInteger():

yield i.getInteger()

else:

i = i.getList()

for j in build_generator(i):

yield j

self.g = build_generator(nestedList)

def next(self):

"""

:rtype: int

"""

#print(self.v)

return self.v

def hasNext(self):

"""

:rtype: bool

"""

try:

self.v = next(self.g)

#print(self.v)

return True

except:

return False

整体代码

以方法1为例,大家可以把下面的代码段粘贴运行,熟悉整个工作流程。

def create_nested_list(l):

"""

构造一个嵌套列表。

:param l:

:return:

"""

res_lst = []

for item in l:

if isinstance(item, int):

res_lst.append(NestedInteger(item))

elif isinstance(item, list):

res_lst.append(create_nested_list(item))

return NestedInteger(res_lst)

def flatten_nested_list(lst):

"""

将嵌套列表扁平化。

:param lst:

:return:

"""

res = []

def dfs(l):

if isinstance(l, NestedInteger):

l = l.getInteger() if l.isInteger() else l.getList()

for item in l:

assert isinstance(item, NestedInteger)

if item.isInteger():

res.append(item.getInteger())

else:

dfs(item.getList())

dfs(lst)

return res

class NestedInteger:

def __init__(self, value):

self.value = value

def isInteger(self) -> bool:

"""

@return True if this NestedInteger holds a single integer, rather than a nested list.

"""

return isinstance(self.value, int)

def getInteger(self) -> int:

"""

@return the single integer that this NestedInteger holds, if it holds a single integer

Return None if this NestedInteger holds a nested list

"""

assert isinstance(self.value, int)

return self.value

def getList(self):

"""

@return the nested list that this NestedInteger holds, if it holds a nested list

Return None if this NestedInteger holds a single integer

"""

assert isinstance(self.value, list)

return self.value

class NestedIterator:

"""

嵌套列表迭代器

"""

def __init__(self, nestedList):

self.flat_list = flatten_nested_list(nestedList)

self.point = 0

self.length = len(self.flat_list)

def next(self) -> int:

self.point += 1

return self.flat_list[self.point-1]

def hasNext(self) -> bool:

return self.point < self.length

if __name__ == "__main__":

nestedList = [[1,1],2,[1,1]]

nestedList = create_nested_list(nestedList).value

# print(flatten_nested_list(nestedList))

i, v = NestedIterator(nestedList), []

while i.hasNext():

v.append(i.next())

print(v)

如有疑问或建议,欢迎评论区留言~

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值