[ 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))
複製代碼

能夠直接執行哈!

相關文章
相關標籤/搜索