二叉树 | 110.平衡二叉树 257. 二叉树的所有路径 404.左叶子之和 222.完全二叉树的节点个数

110.平衡二叉树

题目链接: 110.平衡二叉树 - 力扣(LeetCode)
文章讲解:代码随想录
视频讲解:后序遍历求高度,高度判断是否平衡 | LeetCode:110.平衡二叉树

思路

  1. 递归:前序遍历的写法
  2. 可以用迭代法做

递归

class Solution:
    def isBalanced(self, root: Optional[TreeNode]) -> bool:
        res = True
        def recur(root):
            nonlocal res
            if not root:
                return 0 
            l = recur(root.left)
            r = recur(root.right)
            if abs(l-r) > 1:
                res = False
            return max(l,r)+1
        recur(root)
        return res

递归【另一种写法】

class Solution:
    def isBalanced(self, root: Optional[TreeNode]) -> bool:
        def high(root):
            if not root:
                return 0
            l = high(root.left)
            # -1 表示已经不是平衡二叉树了,否则返回值是以该节点为根节点树的高度
            if l == -1:
                return -1
            r = high(root.right)
            if r == -1:
                return -1
            if abs(l-r) > 1:
                return -1
            return max(l,r)+1
        return high(root) != -1

257. 二叉树的所有路径

题目链接: 257. 二叉树的所有路径 - 力扣(LeetCode)
文章讲解:代码随想录
视频讲解:递归中带着回溯,你感受到了没?| LeetCode:257. 二叉树的所有路径

思路

  1. 递归:其中用到了回溯的思想
  2. 迭代

递归

class Solution:
    def binaryTreePaths(self, root: Optional[TreeNode]) -> List[str]:
        res = []
        def recur(root,path):
            nonlocal res
            if not root:
                return
            if not root.left and not root.right:
                res.append(path)
            if root.left:
                recur(root.left,path+'->'+str(root.left.val))	# 回溯
            if root.right:
                recur(root.right,path+'->'+str(root.right.val))
        
        recur(root,str(root.val))
        return res

迭代

class Solution:
    def binaryTreePaths(self, root: Optional[TreeNode]) -> List[str]:
        res = []
        stack = [root]
        path_stack = [str(root.val)]
        while stack:
            node = stack.pop()
            path = path_stack.pop()
            if not node.left and not node.right:
                res.append(path)
            if node.right:
                stack.append(node.right)
                path_stack.append(path+'->'+str(node.right.val))
            if node.left:
                stack.append(node.left)
                path_stack.append(path+'->'+str(node.left.val))
        return res

404.左叶子之和

题目链接: 404.左叶子之和- 力扣(LeetCode)
文章讲解:代码随想录
视频讲解:二叉树的题目中,总有一些规则让你找不到北 | LeetCode:404.左叶子之和

思路

  1. 递归【也可以通过节点的父节点来判断其左孩子是不是左叶子】
  2. 迭代

递归

class Solution:
    def sumOfLeftLeaves(self, root: Optional[TreeNode]) -> int:
        res = 0
        def recur(root,flag):
            nonlocal res
            if not root:
                return
            if not root.left and not root.right and flag:
                res += root.val
            if root.left:
                recur(root.left,1)
            if root.right:
                recur(root.right,0)
        recur(root,0)
        return res

迭代

class Solution:
    def sumOfLeftLeaves(self, root: Optional[TreeNode]) -> int:
        res = 0
        stack = [(root,0)]
        while stack:
            node,flag = stack.pop()
            if not node.left and not node.right and flag:
                res += node.val
            if node.right:
                stack.append((node.right,0))
            if node.left:
                stack.append((node.left,1))
        return res

222.完全二叉树的节点个数

题目链接: 222.完全二叉树的节点个数- 力扣(LeetCode)
文章讲解:代码随想录
视频讲解:看起来好像做过,一写就错! | LeetCode:111.二叉树的最小深度

思路

  1. 一般解法,时间复杂度O(n)
  2. 考虑完全二叉树特性,时间复杂度O(logn*logn)。每次计算满二叉树的时候,计算的其实就是当前树高,即 O(logn),每次递归调用的都是下一层的子树,总共调用了“树的高度”次,即 O(logn),所以时间复杂度为 O(logn) * O(logn)【看的题解】
  3. 迭代法

递归

class Solution:
    def countNodes(self, root: Optional[TreeNode]) -> int:
        res = 0
        def recur(root):
            nonlocal res
            if not root:
                return
            res += 1
            if root.left:
                recur(root.left)
            if root.right:
                recur(root.right)
        recur(root)
        return res

递归【优化时间复杂度】

class Solution:
    def countNodes(self, root: Optional[TreeNode]) -> int:
        if not root:
            return 0
        l_height = self.getHeight(root.left)
        r_height = self.getHeight(root.right)
        if l_height == r_height: # 左子树高度等于右子树,则左子树为满二叉树
            return 2**l_height+self.countNodes(root.right)
        else: # 左子树高度大于右子树,右子树为满二叉树
            return 2**r_height+self.countNodes(root.left)

    def getHeight(self,root):
        count = 0
        while root:
            root = root.left
            count += 1
        return count

迭代

class Solution:
    def countNodes(self, root: Optional[TreeNode]) -> int:
        if not root:
            return 0
        stack = [root]
        res = 0
        while stack:
            node = stack.pop()
            l_height = self.getHeight(node.left)
            r_height = self.getHeight(node.right)
            if l_height == r_height: # 左子树高度等于右子树,则左子树为满二叉树
                res += 2**l_height
                if node.right:
                    stack.append(node.right)
            else: # 左子树高度大于右子树,右子树为满二叉树
                res += 2**r_height
                if node.left:
                    stack.append(node.left)
        return res


    def getHeight(self,root):
        count = 0
        while root:
            root = root.left
            count += 1
        return count
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值