leetCode,二叉树的对称性、深度

1. 基础部分

该部分的基本思想为层次遍历(循环结构)。

1.1 二叉树的对称性

首先要明确,二叉树的对称性是指整棵树的结构上的对称性,而不仅仅是一个节点的左右两节点对称。因此,这种对称性不要求一个节点如果有左节点,就必须有右节点;只是要求整体上对称,有几种情况如下,

图1. 对称二叉树

判断一棵树是否是对称二叉树,不仅要考虑每个节点的val是否对称,也要考虑结构是否对称。栈,具有后进先出的特性,在遇到对称位置的元素时,如果是对称的元素,那么弹出栈,否则返回即可。因此,判断一棵二叉树是否为对称二叉树的关键点在于,补齐二叉树,并根据对称位置的元素判断,是否对称。如下,

对每层初始化一个栈stack,list

(1)对每一层,在树的左半部分,即该层遍历的下表i<2*(n-1).

如果有左/又子节点,则list.append(val),否则,list.append(None)

(2)在树的右半部分,如果对应位置的元素=stack[-1],则最后元素匹配,弹出栈,否则,返回False。

若每一层遍历结束后stack=[],返回True。

1.2 二叉树的深度

最大深度

按照层次遍历,每当遍历一层,二叉树的最大深度+1.

最小深度

最小深度为从根节点到最邻近的叶子节点的层数。而叶子节点是指既没有左子节点,也没有右子节点的节点,当遇到这样的节点时,返回当前的深度即可。(注意,不是说,一层中不满就是最小深度,如下)

 图2. 二叉树的最小深度

在结构2中,不是说第二层不满,那么min_llevel = 2.同时,结构1中第二层满了,但是其min_level为2.因此,关键为判断一个节点是否为叶子节点。关键代码如下,

if node.left == None and node.right== None:
    return r

树的节点数

同样根据层次遍历的思路,按层一次访问数的节点,得到树的节点数。

2. LeetCode代码

2.1 LeetCode101,对称二叉树

题目来源:力扣

给你一个二叉树的根节点 root , 检查它是否轴对称。

 图3. 对称二叉树示例

2.2 LeetCode104,二叉树的最大深度

题目来源:力扣

给定一个二叉树,找出其最大深度。

二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。

说明: 叶子节点是指没有子节点的节点。

 图4. 二叉树的最大深度示例

2.3 LeetCode111. 二叉树的最小深度

题目来源:力扣

给定一个二叉树,找出其最小深度。

最小深度是从根节点到最近叶子节点的最短路径上的节点数量。

说明:叶子节点是指没有子节点的节点。

 图5. 二叉树的最小深度示例

2.4 LeetCode222. 完全二叉树的节点个数

题目来源:力扣

给你一棵 完全二叉树 的根节点 root ,求出该树的节点个数。

完全二叉树 的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层,则该层包含 1~ 2h 个节点。

图6. 完全二叉树的节点个数

 2.5 代码

代码如下,

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

    def set_left(self, left):
        self.left = left

    def set_right(self, right):
        self.right = right

class Solution(object):
    def isSymmetric(self, root):
        """
        :type root: TreeNode
        :rtype: bool
        """
        # 一层一层地判断
        if root == None:
            return True
        elif root.left == None and root.right == None:
            return True
        elif root.left != None and root.right == None or root.left == None and root.right != None:
            return False
        else:
            node = [root.left, root.right]

        stack = []
        level = 1
        while set(node) != {None}:
            tmp_node = []
            for i in range(len(node)):
                if node[i] == None:
                    tmp_node.append(None)
                    tmp_node.append(None)
                else:
                    if node[i].left != None:
                        tmp_node.append(node[i].left)
                    else:
                        tmp_node.append(None)
                    if node[i].right != None:
                        tmp_node.append(node[i].right)
                    else:
                        tmp_node.append(None)

                if i < 2**(level-1):
                    if node[i] != None:
                        stack.append(node[i].val)
                    else:
                        stack.append(None)
                else:
                    if node[i] != None:
                        if node[i].val == stack[-1]:
                            stack.pop(-1)
                        else:
                            return False
                    else:
                        if stack[-1] == None:
                            stack.pop(-1)
                        else:
                            return False
            if stack != []:
                return False
            node = tmp_node
            level += 1
        return True
    
    def maxDepth(self, root):
        """
        :type root: TreeNode
        :rtype: int
        """
        r = 0
        if root == None:
            return r
        current = [root]
        while current != []:
            r += 1
            tmp = []
            for node in current:
                if node.left != None:
                    tmp.append(node.left)
                if node.right != None:
                    tmp.append(node.right)
            current = tmp
        return r
    
    def minDepth(self, root):
        """
        :type root: TreeNode
        :rtype: int
        """
        r = 0
        if root == None:
            return r
        current = [root]
        while current != []:
            r += 1
            tmp = []
            for node in current:
                if node.left == None and node.right== None:
                    return r
                if node.left != None:
                    tmp.append(node.left)
                if node.right != None:
                    tmp.append(node.right)
            current = tmp
        return r
    
    def countNodes(self, root):
        """
        :type root: TreeNode
        :rtype: int
        """
        r = 0
        if root == None:
            return r
        r += 1
        current = [root]
        while current != []:
            tmp = []
            for node in current:
                if node.left != None:
                    tmp.append(node.left)
                    r += 1
                if node.right != None:
                    tmp.append(node.right)
                    r += 1
            current = tmp
        return r

if __name__ == '__main__':
    root = [1, 2, 2, 3, 4, 4, 3]
    root = [1,  2, 3]
    node1 = TreeNode(1)
    node2 = TreeNode(2)
    node3 = TreeNode(2)
    node4 = TreeNode(3)
    node5 = TreeNode(4)
    node6 = TreeNode(4)
    node7 = TreeNode(3)

    node1.set_left(node2)
    node1.set_right(node3)

    node2.set_left(node4)
    node2.set_right(node5)

    node3.set_left(node6)
    node3.set_right(node7)

    sol = Solution()
    # r = sol.preorderTraversal(node1)
    r = sol.isSymmetric(node1)
    level = sol.maxDepth(node1)
    n_node = sol.countNodes(node1)
    print(r)
    print(level)
    print(n_node)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值