diff --git a/problems/0102.二叉树的层序遍历.md b/problems/0102.二叉树的层序遍历.md index a57a92aa..8ca46368 100644 --- a/problems/0102.二叉树的层序遍历.md +++ b/problems/0102.二叉树的层序遍历.md @@ -87,26 +87,31 @@ public: python代码: -```python +```python3 class Solution: + """二叉树层序遍历迭代解法""" + def levelOrder(self, root: TreeNode) -> List[List[int]]: + results = [] if not root: - return [] + return results + + from collections import deque + que = deque([root]) + + while que: + size = len(que) + result = [] + for _ in range(size): + cur = que.popleft() + result.append(cur.val) + if cur.left: + que.append(cur.left) + if cur.right: + que.append(cur.right) + results.append(result) - queue = [root] - out_list = [] - - while queue: - length = len(queue) - in_list = [] - for _ in range(length): - curnode = queue.pop(0) # (默认移除列表最后一个元素)这里需要移除队列最头上的那个 - in_list.append(curnode.val) - if curnode.left: queue.append(curnode.left) - if curnode.right: queue.append(curnode.right) - out_list.append(in_list) - - return out_list + return results ``` java: @@ -274,29 +279,29 @@ python代码: ```python class Solution: + """二叉树层序遍历II迭代解法""" + def levelOrderBottom(self, root: TreeNode) -> List[List[int]]: + results = [] if not root: - return [] - quene = [root] - out_list = [] + return results - while quene: - in_list = [] - for _ in range(len(quene)): - node = quene.pop(0) - in_list.append(node.val) - if node.left: - quene.append(node.left) - if node.right: - quene.append(node.right) - - out_list.append(in_list) - - out_list.reverse() - return out_list - -# 执行用时:36 ms, 在所有 Python3 提交中击败了92.00%的用户 -# 内存消耗:15.2 MB, 在所有 Python3 提交中击败了63.76%的用户 + from collections import deque + que = deque([root]) + + while que: + result = [] + for _ in range(len(que)): + cur = que.popleft() + result.append(cur.val) + if cur.left: + que.append(cur.left) + if cur.right: + que.append(cur.right) + results.append(result) + + results.reverse() + return results ``` Java: @@ -628,32 +633,29 @@ python代码: ```python class Solution: + """二叉树层平均值迭代解法""" + def averageOfLevels(self, root: TreeNode) -> List[float]: + results = [] if not root: - return [] + return results - quene = deque([root]) - out_list = [] - - while quene: - in_list = [] - - for _ in range(len(quene)): - node = quene.popleft() - in_list.append(node.val) - if node.left: - quene.append(node.left) - if node.right: - quene.append(node.right) - - out_list.append(in_list) - - out_list = map(lambda x: sum(x) / len(x), out_list) - - return out_list + from collections import deque + que = deque([root]) -# 执行用时:56 ms, 在所有 Python3 提交中击败了81.48%的用户 -# 内存消耗:17 MB, 在所有 Python3 提交中击败了89.68%的用户 + while que: + size = len(que) + sum_ = 0 + for _ in range(size): + cur = que.popleft() + sum_ += cur.val + if cur.left: + que.append(cur.left) + if cur.right: + que.append(cur.right) + results.append(sum_ / size) + + return results ``` java: @@ -823,52 +825,28 @@ public: python代码: ```python - class Solution: + """N叉树的层序遍历迭代法""" + def levelOrder(self, root: 'Node') -> List[List[int]]: + results = [] if not root: - return [] + return results - quene = deque([root]) - out_list = [] - - while quene: - in_list = [] - - for _ in range(len(quene)): - node = quene.popleft() - in_list.append(node.val) - if node.children: - # 这个地方要用extend而不是append,我们看下面的例子: - # In [18]: alist=[] - # In [19]: alist.append([1,2,3]) - # In [20]: alist - # Out[20]: [[1, 2, 3]] - # In [21]: alist.extend([4,5,6]) - # In [22]: alist - # Out[22]: [[1, 2, 3], 4, 5, 6] - # 可以看到extend对要添加的list进行了一个解包操作 - # print(root.children),可以得到children是一个包含 - # 孩子节点地址的list,我们使用for遍历quene的时候, - # 希望quene是一个单层list,所以要用extend - # 使用extend的情况,如果print(quene),结果是 - # deque([<__main__.Node object at 0x7f60763ae0a0>]) - # deque([<__main__.Node object at 0x7f607636e6d0>, <__main__.Node object at 0x7f607636e130>, <__main__.Node object at 0x7f607636e310>]) - # deque([<__main__.Node object at 0x7f607636e880>, <__main__.Node object at 0x7f607636ef10>]) - # 可以看到是单层list - # 如果使用append,print(quene)的结果是 - # deque([<__main__.Node object at 0x7f18907530a0>]) - # deque([[<__main__.Node object at 0x7f18907136d0>, <__main__.Node object at 0x7f1890713130>, <__main__.Node object at 0x7f1890713310>]]) - # 可以看到是两层list,这样for的遍历就会报错 - - quene.extend(node.children) - - out_list.append(in_list) + from collections import deque + que = deque([root]) - return out_list - -# 执行用时:60 ms, 在所有 Python3 提交中击败了76.99%的用户 -# 内存消耗:16.5 MB, 在所有 Python3 提交中击败了89.19%的用户 + while que: + result = [] + for _ in range(len(que)): + cur = que.popleft() + result.append(cur.val) + # cur.children 是 Node 对象组成的列表,也可能为 None + if cur.children: + que.extend(cur.children) + results.append(result) + + return results ``` java: diff --git a/problems/二叉树的迭代遍历.md b/problems/二叉树的迭代遍历.md index a1d65070..84363610 100644 --- a/problems/二叉树的迭代遍历.md +++ b/problems/二叉树的迭代遍历.md @@ -27,7 +27,7 @@ 我们先看一下前序遍历。 -前序遍历是中左右,每次先处理的是中间节点,那么先将跟节点放入栈中,然后将右孩子加入栈,再加入左孩子。 +前序遍历是中左右,每次先处理的是中间节点,那么先将根节点放入栈中,然后将右孩子加入栈,再加入左孩子。 为什么要先加入 右孩子,再加入左孩子呢? 因为这样出栈的时候才是中左右的顺序。 @@ -140,7 +140,7 @@ public: # 总结 -此时我们用迭代法写出了二叉树的前后中序遍历,大家可以看出前序和中序是完全两种代码风格,并不想递归写法那样代码稍做调整,就可以实现前后中序。 +此时我们用迭代法写出了二叉树的前后中序遍历,大家可以看出前序和中序是完全两种代码风格,并不像递归写法那样代码稍做调整,就可以实现前后中序。 **这是因为前序遍历中访问节点(遍历节点)和处理节点(将元素放进result数组中)可以同步处理,但是中序就无法做到同步!**