1. 程式人生 > >LeetCode程式設計集訓第4次

LeetCode程式設計集訓第4次

一、二叉樹的概念

  • 是一種資料結構,它是由n(n>=1)個有限結點組成一個具有層次關係的集合。

     特點:
   (1)每個結點有零個或多個子結點
   (2)沒有父節點的結點稱為根節點
   (3)每一個非根結點有且只有一個父節點
   (4)除了根結點外,每個子結點可以分為多個不相交的子樹。

  • 二叉樹是每個結點最多有兩個子樹的樹結構。它有五種基本形態:二叉樹可以是空集;根可以有空的左子樹或右子樹;或者左、右子樹皆為空。

      特點:
   (1)二叉樹第i層上的結點數目最多為2i-1(i>=1)
   (2)深度為k的二叉樹至多有2k-1個結點(k>=1)
   (3)包含n個結點的二叉樹的高度至少為(log2n)+1
   (4)在任意一棵二叉樹中,若終端結點的個數為n0,度為2的結點數為n2,則n0=n2+1

 

  • 滿二叉樹是高度為h,並且由2h-1個結點組成的二叉樹,稱為滿二叉樹
  • 完全二叉樹是一棵二叉樹中,只有最下面兩層結點的度可以小於2,並且最下層的葉結點集中在靠左的若干位置上,這樣的二叉樹稱為完全二叉樹。

二、二叉樹遍歷

二叉樹遍歷:從樹的根節點出發,按照某種次序依次訪問二叉樹中所有的結點,使得每個結點被訪問僅且一次。
1、前序遍歷
基本思想:先訪問根結點,再先序遍歷左子樹,最後再先序遍歷右子樹即根—左—右。
2、中序遍歷
基本思想:先中序遍歷左子樹,然後再訪問根結點,最後再中序遍歷右子樹即左—根—右。
3、後序遍歷
基本思想:先後序遍歷左子樹,然後再後序遍歷右子樹,最後再訪問根結點即左—右—根。
4、層次遍歷
基本思想:用一個佇列儲存被訪問的當前節點的左右孩子以實現層序遍歷。

三、程式設計練習

第一題(98)

內容描述:

給定一個二叉樹,判斷其是否是一個有效的二叉搜尋樹。

假設一個二叉搜尋樹具有如下特徵:

  • 節點的左子樹只包含小於當前節點的數。
  • 節點的右子樹只包含大於當前節點的數。
  • 所有左子樹和右子樹自身必須也是二叉搜尋樹。

示例 1:

輸入:
    2
   / \
  1   3
輸出: true

示例 2:

輸入:
    5
   / \
  1   4
     / \
    3   6
輸出: false
解釋: 輸入為: [5,1,4,null,null,3,6]。
     根節點的值為 5 ,但是其右子節點值為 4 。

解題方案:

思路:

用遞迴的思想。
如果節點為空,則返回True。
若左子樹不空的時候,其根結點大於左子樹的最大值——左子樹的右下角的結點。
左子樹返回為真且右子樹也為真則返回真。考慮右子樹時,根要比右子樹的最小值小—最左左下角的結點。

程式碼:

class Solution(object):
    def isValidBST(self, root):
        """
        :type root: TreeNode
        :rtype: bool
        """
        return self.valid(root, None, None)

    def valid(self, root, min, max):
        if root == None or root.val == None:
            return True

        if (min is not None and root.val <= min) or (max is not None and root.val >= max):
            print(1)
            return False

        return self.valid(root.left, min, root.val) and self.valid(root.right, root.val, max)

執行結果:

第二題(102)

內容描述:

給定一個二叉樹,返回其按層次遍歷的節點值。 (即逐層地,從左到右訪問所有節點)。

例如:
給定二叉樹: [3,9,20,null,null,15,7],

    3
   / \
  9  20
    /  \
   15   7

返回其層次遍歷結果:

[
  [3],
  [9,20],
  [15,7]
]

解題方案:

思路:

用深度優先搜尋(DFS),節點的深度與輸出結果陣列的下標相對應。

程式碼:

class Solution(object):
    def levelOrder(self, root):
        """
        :type root: TreeNode
        :rtype: List[List[int]]
        """
        res = [] 
        self.dfs(root, 0, res) 
        return res 
    def dfs(self, root, depth, res): 
        if root == None: 
            return res 
        if len(res) < depth+1: 
            res.append([]) 
        res[depth].append(root.val) 
        self.dfs(root.left, depth+1, res) 
        self.dfs(root.right, depth+1, res)

執行結果:

第三題(107)

內容描述:

給定一個二叉樹,返回其節點值自底向上的層次遍歷。 (即按從葉子節點所在層到根節點所在的層,逐層從左向右遍歷)

例如:
給定二叉樹 [3,9,20,null,null,15,7],

    3
   / \
  9  20
    /  \
   15   7

返回其自底向上的層次遍歷為:

[
  [15,7],
  [9,20],
  [3]
]

解題方案:

思路:

採用層次遍歷法,並翻轉。

程式碼:

class Solution(object):
    def help(self, root, level, ans):
        if root:
            if len(ans) < level + 1:
                ans.append([])
            ans[level].append(root.val)
            self.help(root.left, level + 1, ans)
            self.help(root.right, level + 1, ans)

    def levelOrderBottom(self, root):
        """
        :type root: TreeNode
        :rtype: List[List[int]]
        """
        ans = []
        self.help(root, 0, ans)
        ans.reverse()
        return ans  

執行結果:

四、往期回顧

【任務一】
陣列:學習雜湊表思想,並完成leetcode上的兩數之和(1)及Happy    Number(202)!(要求全部用雜湊 思想實現!)https://shimo.im/sheet/xjO2SX8fJJkRTJ4s/ 《DW程式設計集訓第二期-任務1》,可複製連結 後用石墨文件 App 開啟
【任務二】
連結串列:學習單鏈表知識,實踐環形連結串列(142,要求至少兩種方法!)及反轉一個單鏈表(206),不限制語  言!https://shimo.im/sheet/1wghoDz457oLIOqh/ 《DW程式設計集訓第二期-任務2》,可複製連結後用石墨 文件 App 開啟
【任務三】
佇列及堆:學習佇列思想及堆排序思想,並完成leetcode上的返回滑動視窗中的最大值(239)!並同  時 溫習前二天內容,做出總結!https://shimo.im/sheet/oXtdW7eadnk3p6Jh/