[ LeetCode 107 ] N叉树层序遍历

20210720.png

读前福利:几百本互联网技术书籍送给你们node

天天分享一个LeetCode题目python

天天 5 分钟,一块儿进步面试

LeetCode N叉树层序遍历,地址: leetcode-cn.com/problems/n-…数组

树结点类

class Node(object):
    def __init__(self, val=None, children=[]):
        self.val = val
        self.children = children
复制代码

N叉树的特殊性,就是一个结点可能会包含N个结点,因此,每一个结点的孩子结点设置为数组markdown

层序遍历

层序遍历对于不少时候,都是面试常常问到的内容。app

尤为是这里有个小点,可能会让你们咯噔一下,就是对于结点的打印方式。oop

好比,树的结构是:post

A
   / | \
  B  C  D
 /|\   / \
E F G H   I
复制代码

结果打印的方式会有两种:ui

一种是普通遍历,直接打印spa

另一种是每一个层级中的元素单独打印,也是LeetCode429 要求的格式

# 第一种
['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I']
# 第二种
[['A'], ['B', 'C', 'D'], ['E', 'F', 'G', 'H', 'I']]
复制代码

第一种很简单,第二种可能须要一些小小的中间结果记录,我们分开说说...

第一种层序遍历

1.初始化结果集res,初始化队列queue,将根结点放置到queue中;

2.只要queue不为空,循环遍历,每次遍历将队首元素防止到 res 中,以后将队首元素的孩子结点依次入队;

3.循环执行第 2 点。

看看代码:

def levelOrder_basic(self, root):
	  # 初始化结果集res
    res = []
    # 初始化队列queue,将根结点放置到queue中
    queue = collections.deque()
    queue.appendleft(root)
    while(queue):
      	# 每次遍历将队首元素防止到 res 中
        pop_node = queue.pop()
        res.append(pop_node.val)
        # 将队首元素的孩子结点依次入队
        for node in pop_node.children:
            queue.appendleft(node)
    return res
复制代码

其实比较简单,就是将遍历到的结点放置到结果集中,同时将结点的孩子结点入队,以后循环进行就好!

第二种层序遍历

这种遍历,有一点难处就是要将每一层级的元素单独放置到数组中,而后将每一层级的数组放置到最后的数组中

这样:

[['A'], ['B', 'C', 'D'], ['E', 'F', 'G', 'H', 'I']]
复制代码

相似于 第一种 层序遍历,须要改变的就是要将每一层级的元素单独遍历

1.初始化结果集res,初始化队列queue,将根结点放置到queue中;

(注意:此处的queue放置的是每一层的结点元素,不理解不要紧,往下看)

2.只要queue不为空,循环遍历,同时初始化两个临时数组

第一个:tmp_res = [],临时存放每一层遍历访问到的结点,最终会合并到结果res中

第二个:tmp_queue = [],临时存放下一层的结点元素,用于下一个循环的遍历

每次遍历将队首元素防止到 tmp_res 中,以后将队首元素的孩子结点依次入队 tmp_queue

最后,将 tmp_queue 赋值给 queue,tmp_res并入到最终结果集 res

3.循环执行第 2 点,直到 queue 为空

4.返回最终结果集 res

看代码

def levelOrder(self, root):
    # 最终结果
    res = []
    if not root:
        return res

    # 初始化队列,而且将根结点置入队列中
    # 存放每个层级的结点
    queue = collections.deque()
    queue.appendleft(root)
    while(queue):
        # 临时存放结点的队列,最终合并到最后的 res 中
        tmp_res = []
        # 临时存放下一层结点的队列
        tmp_queue = []
        for node in queue:
            tmp_res.append(node.val)
            # 将孩子结点放置到 tmp_queue 中
            for child_node in node.children:
                tmp_queue.append(child_node)
        # 将 tmp_queue 赋值给 queue,tmp_res并入到最终结果集 res
        queue = tmp_queue
        res.append(tmp_res)
复制代码

看着比较复杂,其实关键有一点,以前循环遍历 queue 就好,如今是把每一层结点动态的赋值给 queue,也就是说每一次循环遍历,queue 中的值是当前层的结点集。

动手画一画就会看起来很简单了哈!

所有代码

# -*- coding:utf-8 -*-
# !/usr/bin/env python

import collections

# 树结点类
class Node(object):
    def __init__(self, val=None, children=[]):
        self.val = val
        self.children = children


class Solution(object):
    def levelOrder_basic(self, root):
        """ 基础的层序遍历,就是把每一层的结点值一次性打印出来 相似于 ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I'] 这样 :param root: :return: """
        res = []
        queue = collections.deque()
        queue.appendleft(root)
        while(queue):
            pop_node = queue.pop()
            res.append(pop_node.val)
            for node in pop_node.children:
                queue.appendleft(node)
        return res





    def levelOrder(self, root):
        """ 层序遍历(LeetCode中规定的格式),即把每一层的结点放进各自的数组中 相似于[['A'], ['B', 'C', 'D'], ['E', 'F', 'G', 'H', 'I']] 这样 :param root: :return: """
        # 最终结果
        res = []
        if not root:
            return res

        # 初始化队列,而且将根结点置入队列中
        # 存放每个层级的结点
        queue = collections.deque()
        queue.appendleft(root)
        while(queue):
            # 临时存放结点的队列,最终合并到最后的 res 中
            tmp_res = []
            # 临时存放下一层结点的队列
            tmp_queue = []
            for node in queue:
                tmp_res.append(node.val)
                # 将孩子结点放置到 tmp_queue 中
                for child_node in node.children:
                    tmp_queue.append(child_node)
            queue = tmp_queue
            res.append(tmp_res)

        return res


if __name__ == "__main__":
    # 新建节点
    root = Node('A')
    node_B = Node('B')
    node_C = Node('C')
    node_D = Node('D')
    node_E = Node('E')
    node_F = Node('F')
    node_G = Node('G')
    node_H = Node('H')
    node_I = Node('I')
    # 构建三叉树
    # A
    # / | \
    # B C D
    # /|\ / \
    # E F G H I
    root.children = [node_B, node_C, node_D]
    node_B.children = [node_E, node_F, node_G]
    node_D.children = [node_H, node_I]

    s = Solution()
    print(s.levelOrder_basic(root))
    print(s.levelOrder(root))
复制代码

能够直接执行哈!