1. 程式人生 > >Leetcode——初級部分——樹部分——Python實現

Leetcode——初級部分——樹部分——Python實現

一.二叉樹的最大深度

給定一個二叉樹,找出其最大深度。

二叉樹的深度為根節點到最遠葉子節點的最長路徑上的節點數。

說明: 葉子節點是指沒有子節點的節點。

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

    3
   / \
  9  20
    /  \
   15   7

返回它的最大深度 3 。

我的解答:

如果根節點為空,則深度為0,返回0,遞迴的出口

如果根節點不為空,那麼深度至少為1,然後我們求他們左右子樹的深度

比較左右子樹深度值,返回較大的那一個

通過遞迴呼叫

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def maxDepth(self, root):
        """
        :type root: TreeNode
        :rtype: int
        """
        left = 1
        right = 1
        if not root:
            return 0
        else:
            left = left + self.maxDepth(root.left)
            right = right + self.maxDepth(root.right)
            if left >= right:
                return left
            else:
                return right  

二.驗證二叉搜尋樹

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

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

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

示例 1:

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

示例 2:

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

我的解答:

1.這個解答有問題——忽略了隔層之間可能存在不符合規定的可能性

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def isValidBST(self, root):
        """
        :type root: TreeNode
        :rtype: bool
        """
        #根節點為None的情況——返回True
        if not root:
            return True
        else:
            #沒有葉子結點,搜尋到了終點,返回True
            if not root.left and not root.right:
                return True
            #沒有左邊結點、右邊結點滿足二叉搜尋樹條件情況
            elif not root.left:
                if root.right.val > root.val:
                    return self.isValidBST(root.right)
                else:
                    return False
            #沒有右邊結點、左邊結點滿足二叉搜尋樹條件情況
            elif not root.right:
                if root.left.val < root.val:
                    return self.isValidBST(root.left)
                else:
                    return False
            #左右結點均滿足二叉搜尋樹條件情況
            elif root.left.val < root.val and root.right.val > root.val:
                return self.isValidBST(root.left) and self.isValidBST(root.right)
            #左右結點只要有一個不滿足二叉搜尋樹情況
            else:
                return False

2.正確的解答

從上往下比較,每個節點往左就是最大,往右就是最小值

傳輸過程中原函式不能夠傳遞最大最小值,又重新定義了一個函式呼叫

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def isValidBST(self, root):
        """
        :type root: TreeNode
        :rtype: bool
        """
        return self.isValidBST_f2(root,-2**32,2**32-1)
        
    #從上往下比較,每個節點往左就是最大,往右就是最小值
    #傳輸過程中原函式不能夠傳遞最大最小值,又重新定義了一個函式呼叫
    def isValidBST_f2(self,root,small,large):
        if not root:
            return True
        elif root.val >= large or root.val <= small:
            return False
        else:
            return self.isValidBST_f2(root.left,small,root.val) and self.isValidBST_f2(root.right,root.val,large)

三.對稱二叉樹

給定一個二叉樹,檢查它是否是映象對稱的。

例如,二叉樹 [1,2,2,3,4,4,3] 是對稱的。

    1
   / \
  2   2
 / \ / \
3  4 4  3

但是下面這個 [1,2,2,null,3,null,3] 則不是映象對稱的:

    1
   / \
  2   2
   \   \
   3    3

說明:

如果你可以運用遞迴和迭代兩種方法解決這個問題,會很加分。

我的解答:

這裡將根節點的左右節點假設成兩顆獨立的樹,這樣解題跟題目100就是類似的了,區別:遞迴呼叫時,因是對稱,所以是左樹左節點與右樹右節點,左樹右節點與右樹左節點 

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def isSymmetric(self, root):
        """
        :type root: TreeNode
        :rtype: bool
        """
        #這裡將根節點的左右節點假設成兩顆獨立的樹,這樣解題跟100就是類似的了,區別:遞迴呼叫時,因是對稱,所以是左樹左節點與右樹右節點,左樹右節點與右樹左節點 
        #定義
        def isSameTree(p,q):
            if not p and not q: #左右數均為空,返回True
                return True
            elif p and q and p.val == q.val: #遞迴,每次重新從函式入口處進行,每次進行遞迴邊界判斷  
                l = isSameTree(p.left,q.right)
                r = isSameTree(p.right,q.left)
                return l and r
            else:
                return False
        #呼叫
        if not root:
            return True
        else:
            return isSameTree(root.left,root.right)

四.二叉樹的層次遍歷

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

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

    3
   / \
  9  20
    /  \
   15   7
返回其層次遍歷結果:
[
  [3],
  [9,20],
  [15,7]
]

我的解答:

廣度優先搜尋BFS實現

佇列:用一個佇列,把當前點加進去,從這個點開始嘗試所有可能的方向,嘗試完以後把這個點出隊,然後對還在隊裡的點(也就是剛才入隊的點)繼續同樣的步驟,直到達到目的。

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def levelOrder(self, root):
        """
        :type root: TreeNode
        :rtype: List[List[int]]
        """
        #廣度優先搜尋BFS實現(佇列:用一個佇列,把當前點加進去,從這個點開始嘗試所有可能的方向,嘗試完以後把這個點出隊,然後對還在隊裡的點(也就是剛才入隊的點)繼續同樣的步驟,直到達到目的。)
        if not root:
            return []
        
        queue = [root]
        node = []
        res = []
        
        while queue:
            nodes = []
            node_value = []
            
            #下面是把這一層的所有節點的值全部取出來(放入到node_value中)、並且把子節點全部求出來(放入到nodes中)
            for node in queue:
                if node.left:
                    nodes.append(node.left)
                if node.right:
                    nodes.append(node.right)
                node_value = node_value + [node.val]
            
            queue = nodes #子節點儲存到queue變數中
            res.append(node_value) #節點的值儲存在res變數中
        
        return res

 五.將有序陣列轉換為二叉搜尋樹

將一個按照升序排列的有序陣列,轉換為一棵高度平衡二叉搜尋樹。

本題中,一個高度平衡二叉樹是指一個二叉樹每個節點 的左右兩個子樹的高度差的絕對值不超過 1。

示例:

給定有序陣列: [-10,-3,0,5,9],

一個可能的答案是:[0,-3,9,-10,null,5],它可以表示下面這個高度平衡二叉搜尋樹:

      0
     / \
   -3   9
   /   /
 -10  5

我的解答:

本質上是運用二分查詢法!

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def sortedArrayToBST(self, nums):
        """
        :type nums: List[int]
        :rtype: TreeNode
        """
        if not nums:
            return None
        mid = len(nums)//2 #得到中點
        root = TreeNode(nums[mid]) #root為樹的根節點
        #下面是遞迴過程(左子樹和右子樹繼續二分得到中間值)
        root.left = self.sortedArrayToBST(nums[:mid])
        root.right = self.sortedArrayToBST(nums[mid+1:]) #這裡注意——中間節點已經給了root了,所以從mid+1開始
        return root