1. ?LeetCode刷題實戰(zhàn)110:平衡二叉樹

        共 3638字,需瀏覽 8分鐘

         ·

        2020-11-30 22:35

        算法的重要性,我就不多說了吧,想去大廠,就必須要經(jīng)過基礎(chǔ)知識和業(yè)務(wù)邏輯面試+算法面試。所以,為了提高大家的算法能力,這個公眾號后續(xù)每天帶大家做一道算法題,題目就從LeetCode上面選 !

        今天和大家聊的問題叫做?平衡二叉樹,我們先來看題面:
        https://leetcode-cn.com/problems/balanced-binary-tree/
        Given a binary tree, determine if it is height-balanced.

        For this problem, a height-balanced binary tree is defined as:

        a binary tree in which the left and right subtrees of every node differ in height by no more than 1.

        題意


        給定一個二叉樹,判斷它是否是高度平衡的二叉樹。
        本題中,一棵高度平衡二叉樹定義為:
        一個二叉樹每個節(jié)點 的左右兩個子樹的高度差的絕對值不超過 1 。

        樣例

        解題

        https://blog.csdn.net/qq_17550379/article/details/82081501

        對于這個問題,我們可以非??斓膶懗鲞f歸版本。當(dāng)root為空的時候,我們將None也看成是一棵二叉樹,所以返回True。接著我們判斷左子樹高度和右子樹高度差是不是大于1,如果是,那么我們返回False就好啦。如果不是接著遞歸判斷左子樹和右子樹是不是一棵平衡二叉樹。

        class?Solution:????????
        ????def?isBalanced(self, root):
        ????????"""
        ????????:type root: TreeNode
        ????????:rtype: bool
        ????????"""

        ????????if?not?root:
        ????????????return?True

        ????????def?height(node):
        ????????????if?not?node:
        ????????????????return?0

        ????????????return?max(height(node.left), height(node.right)) + 1

        ????????if?abs(height(root.left) - height(root.right)) > 1:
        ????????????return?False

        ????????return?self.isBalanced(root.left) and?self.isBalanced(root.right)


        但是如你所見,這個解法有一個很明顯的弊端,就是我們在每次求height的時候有大量的重復(fù)運算,我們怎么可以避免這種重復(fù)運算呢?或者說我們有什么辦法在遍歷一遍樹(求一次height)的過程中就可以得到答案呢?我們希望當(dāng)左右子樹中存在不平衡的時候就可以提前停止。

        class?Solution:????????
        ????def?isBalanced(self, root):
        ????????"""
        ????????:type root: TreeNode
        ????????:rtype: bool
        ????????"""

        ????????def?height(node):
        ????????????if?not?node:
        ????????????????return?0

        ????????????left = height(node.left)
        ????????????right = height(node.right)
        ????????????if?left == -1?or?right == -1?or?abs(left - right) > 1:
        ????????????????return?-1

        ????????????return?max(left, right) + 1
        ????????
        ????????return?height(root) != -1


        上面這種解法非常的巧妙,當(dāng)樹出現(xiàn)不平衡的時候,我們令樹的高度是-1。

        同樣的,對于可以用遞歸解決的問題,我們都應(yīng)該思考一下怎么可以通過迭代去解決。那這個問題怎么通過迭代解決呢?我們可以先通過BFS得到一個list,然后從list的最后一個節(jié)點回退到root,并且計算節(jié)點的深度差,更新各節(jié)點深度。

        class Solution:
        ????def isBalanced(self, root):
        ????????"""
        ????????:type?root:?TreeNode
        ????????:rtype: bool
        ????????"""
        ????????nodes = [root]
        ????????for?node in nodes:
        ????????????if?node:
        ????????????????nodes.extend([node.left, node.right])

        ????????depths = {}
        ????????nodes.reverse()
        ????????for?node in nodes:
        ????????????if?node:
        ????????????????if?abs(depths.get(node.left, 0) - depths.get(node.right, 0)) > 1:
        ????????????????????return?False

        ????????????????depths[node] = max(depths.get(node.left, 0), depths.get(node.right, 0)) + 1

        ????????return?True



        我們也可以通過前序遍歷的方式去更新節(jié)點的深度。但是這里的問題和之前的Leetcode 144:二叉樹的前序遍歷中有一些區(qū)別,之前的問題中是輸出節(jié)點,而我們這里是要更新節(jié)點。所以我們不能直接將節(jié)點彈出,而是要保留到更新完節(jié)點后再彈出。這要怎么做呢?我們可以通過建立一個tuple包含一個seen信息,表示這個節(jié)點之前是不是訪問過。如果訪問過我們再將節(jié)點彈出,否則的話再將節(jié)點插回去。

        class Solution:
        ????def isBalanced(self, root):
        ????????"""
        ????????:type?root:?TreeNode
        ????????:rtype: bool
        ????????"""
        ????????stack = list()
        ????????stack.append((root, 0))
        ????????depths = {}
        ????????while?stack:
        ????????????node, seen = stack.pop()
        ????????????if?node:
        ????????????????if?not seen:
        ????????????????????stack.extend([(node, 1), (node.right, 0), (node.left, 0)])
        ????????????????if?abs(depths.get(node.left,0) - depths.get(node.right,0)) > 1:
        ????????????????????return?False
        ????????????????depths[node] = max(depths.get(node.left,0), depths.get(node.right,0)) + 1

        ????????return?True


        依照這種思路,我們也可以寫出中序遍歷和后序遍歷的版本。

        好了,今天的文章就到這里,如果覺得有所收獲,請順手點個在看或者轉(zhuǎn)發(fā)吧,你們的支持是我最大的動力。

        更多推文:

        LeetCode1-100題匯總,希望對你有點幫助!

        LeetCode刷題實戰(zhàn)101:對稱二叉樹

        LeetCode刷題實戰(zhàn)102:二叉樹的層序遍歷

        LeetCode刷題實戰(zhàn)103:二叉樹的鋸齒形層次遍歷

        LeetCode刷題實戰(zhàn)104:二叉樹的最大深度

        LeetCode刷題實戰(zhàn)105:從前序與中序遍歷序列構(gòu)造二叉樹

        LeetCode刷題實戰(zhàn)106:從中序與后序遍歷序列構(gòu)造二叉樹
        LeetCode刷題實戰(zhàn)107:二叉樹的層次遍歷 II
        LeetCode刷題實戰(zhàn)108:將有序數(shù)組轉(zhuǎn)換為二叉搜索樹
        LeetCode刷題實戰(zhàn)109:有序鏈表轉(zhuǎn)換二叉搜索樹

        瀏覽 52
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
          
          

            1. 亚洲激情综合网 | 国产美女自慰网站 | 丰满双乳秘书被老板狂揉捏观看 | 久久一级婬A片AAA毛片古代 | 小草回家永不迷路2024ty66 |