【百度一面】怒噴面試官!不就是樹遍歷時增加一個行號?

Python愛好者社群發表於2021-03-05

【0】

前言

年前幾天,來自一個前同事的百度一輪面試題目,不是太難,而且隨即就想出來了,還跟面試官因為題目簡單開了玩笑。抽空大家不妨也作為飯後甜點看看(o)/~

個人感覺這屬於那種見過就一定會的那種題目,如果沒太接觸過這種類似leetcode題目的話,想一下也還是比較簡單的。但是今天還是拿出來,和大家一起分享一下

故事開始→_→【0】

【1】

題目

要求按照下面的格式將樹資訊列印出來,看著很是直觀的列印結果

要求輸出格式

A -> 第一行
B C -> 第二行
D E F -> 第三行
G H -> 第四行

就是按照給定的格式進行結點的列印

【3】

解決方案

很明顯的可以看到,在實現該結果的同時,大致解決思路一定是基於過去我們們看到過的層次遍歷的方式

在層次遍歷的同時,記錄每次換行操作時候的動作

在這所有之前,我們們先給出來結點資訊,以便後面清楚的對圖中二叉樹進行操作

【利用Python看,簡單又直觀】

class TreeNode:
    def __init__(self, value):
        self.val = value		# 結點值
        self.left = None		# 指向做孩子
        self.right = None		# 指向右孩子

需要回顧層次遍歷程式碼的可以翻到文末,進行了層次遍歷的展現,這裡有過去用C語言實現的程式碼

由於題目中要求在列印結點資訊的同時,要求給出結點所在行和列的資訊

利用層次遍歷遍歷的特點(重點!重點!重點!在當前層的所有結點元素入隊之後,上一層最後一個結點元素才會彈出),初始化兩個指標 last 和 cur

  • last 指向上一層最右側結點
  • cur 是當前結點位置【往佇列中輸入的結點】

只有當彈出的元素 與 last 指向的結點相同,說明 cur 也遍歷到了當前層的最右面。此時,可以令 last = cur

具體細節流程,看下面[長長長長長...]圖

以上,基於給定的樹狀結構進行了細緻的說明,供大家參考。另外個人不太喜歡動圖,原因是想要看清楚每一步的時候,不容易控制

對於佇列的操作,利用 Python 的 list 資料結構實現的方式如下

# 入隊
list.append('A')

# 出隊
list.append(0)

下面給出完整程式碼,並且給出構造樹的程式碼已經層次遍歷的程式碼

可以直接貼到自己的環境中進行實現

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

# 樹結點類
class TreeNode:
    def __init__(self, value):
        self.val = value
        self.left = None
        self.right = None


def level_order_traverse(root):
    if not root:
        return
        # 佇列queue
    queue = [root]
    while len(queue) > 0:
        node = queue.pop(0)
        print(node.val, end=" ")
        if node.left:
            queue.append(node.left)
        if node.right:
            queue.append(node.right)


def level_order_traverse_datail(root):
    last, n_last = root, root
    i = 1
    if not root:
        return
    # 佇列queue
    queue = [root]
    while len(queue) > 0:
        node = queue.pop(0)
        print(node.val, end=" ")
        if node.left:
            n_last = node.left
            queue.append(node.left)
        if node.right:
            n_last = node.right
            queue.append(node.right)
        # 當彈出的結點是last指向的結點時,令 last = n_last
        if last is node:
            last = n_last
            print(" -> 第 %d 行" % i)
            i = i + 1


if __name__ == "__main__":
    # 新建節點
    node_A = TreeNode("A")
    node_B = TreeNode("B")
    node_C = TreeNode("C")
    node_D = TreeNode("D")
    node_E = TreeNode("E")
    node_F = TreeNode("F")
    node_G = TreeNode("G")
    node_H = TreeNode("H")

    # 構建二叉樹
    #      A
    #    /   \
    #   B     C
    #  /     / \
    # D     E   F
    #      / \
    #     G   H

    node_A.left, node_A.right = node_B, node_C
    node_B.left = node_D
    node_C.left, node_C.right = node_E, node_F
    node_E.left, node_E.right = node_G, node_H

    # 列印結點元素
    print("層次遍歷結果:")
    level_order_traverse(node_A)

    print("\n層次遍歷結果(列印行號):")
    level_order_traverse_datail(node_A)

相關文章