二叉樹 13 (最大二叉樹 leetcode 654)

思想

二叉樹的核心思想是分治和遞歸,特點是遍歷方式。
解題方式常見兩類思路:

  1. 遍歷一遍二叉樹尋找答案;
  2. 通過分治分解問題尋求答案;

遍歷分為前中后序,本質(zhì)上是遍歷二叉樹過程中處理每個節(jié)點的三個特殊時間點:

  1. 前序是在剛剛進入二叉樹節(jié)點時執(zhí)行;
  2. 后序是在將要離開二叉樹節(jié)點時執(zhí)行;
  3. 中序是左子樹遍歷完進入右子樹前執(zhí)行;
# 前序
     1 node
    /      \
 2 left   3 right
中左右
 
# 中序
     2 node
    /      \
 1 left    3 right
左中右
 
# 后序
     3 node
    /      \
 1 left    2 right     
左右中       

多叉樹只有前后序列遍歷,因為只有二叉樹有唯一一次中間節(jié)點的遍歷

題目的關(guān)鍵就是找到遍歷過程中的位置,插入對應(yīng)代碼邏輯實現(xiàn)場景的目的。

實例

最大二叉樹 leetcode 654

class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right

輸入:
nums: List[int],一個不重復(fù)的整數(shù)數(shù)組

輸出:
TreeNode,根據(jù) nums 構(gòu)建一顆二叉樹,返回根節(jié)點。每個節(jié)點是當(dāng)前 nums 中的最大值,且左子樹是這個值左側(cè)的元素,右子樹是右側(cè)的元素。

舉例:
給定 [3,2,1,6,0,5]
最大值是 6,作為根節(jié)點,左子樹是 [3,2,1],右子樹是 [0,5]
左子樹中最大值是 3,作為左子樹的節(jié)點,他的左子樹是 [],右子樹是 [2,1]
右子樹中最大值是 5,作為右子樹的節(jié)點,他的左子樹是 [0],右子樹是 []
...

    6                 
   / \               
 3    5         
  \   /           
   2 0   
    \
     1      

二叉樹的數(shù)據(jù)存儲可以使用鏈表,也可以使用數(shù)組,往往數(shù)組更容易表達,根節(jié)點從 index=1 處開始存儲,浪費 index=0 的位置
left_child = 2 * parent
right_child = 2 * parent + 1
parent = child // 2

分治解

基本情境是找到當(dāng)前構(gòu)建二叉樹的元素范圍,在這個范圍中找到值最大的元素和下標。
這個元素構(gòu)建一個二叉樹的根節(jié)點,下標左側(cè)是遞歸構(gòu)建二叉樹的新范圍,右側(cè)同理,左右子樹指針連接好后返回當(dāng)前根節(jié)點。

上例中

  • 初始范圍是 0, 5,元素是 [3,2,1,6,0,5],其中的最大值是 6,下標是 3。構(gòu)建一個根節(jié)點 TreeNode(6),6.left = [3,2,1],6.right = [0, 5]
  • 左子樹 [3,2,1] 的范圍是 0,2,,其中的最大值是 3,下標是 0。構(gòu)建一個根節(jié)點 TreeNode(3),3.left = [],3.right = [2,1]
  • ...

編碼


from typing import Optional, List


class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right


def maximum_binary_tree(nums: List[int]) -> Optional[TreeNode]:
    def construct(left: int, right: int) -> Optional[TreeNode]:
        # base 條件,返回樹的葉子的左右子樹的空指針節(jié)點
        if left > right:
            return None
        # 找到范圍中的最大值和下標
        max_int, max_index = None, None
        for i in range(left, right + 1):
            # 初始情況和當(dāng)前值比最大值大時,更新信息
            if max_int is None or nums[i] > max_int:
                max_int, max_index = nums[i], i
        # 構(gòu)建二叉樹
        root = TreeNode(max_int)
        root.left = construct(left, max_index - 1)
        root.right = construct(max_index + 1, right)
        return root
    # 邊界保護
    if len(nums) == 0:
        return None
    return construct(0, len(nums) - 1)

相關(guān)

二叉樹 0
二叉樹 1
二叉樹 2
二叉樹 3
二叉樹 4
二叉樹 5
二叉樹 6
二叉樹 7
二叉樹 8
二叉樹 9
二叉樹 10
二叉樹 11
二叉樹 12

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容