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

110.平衡二叉树

1. 判断是否是平衡二叉树,要去看它左右子树的高度差是否超过了1

2. 求二叉树高度使用后序遍历: 左右中

3. 当我们发现左右任何一个节点,不符合我们这个平衡二叉树的条件,再往上返回的时候就不反回节点高度;

   1. 直接返回-1,告诉上一层树这个不是平衡二叉树

# 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
class Solution(object):
    def isBalanced(self, root):
        """
        :type root: TreeNode
        :rtype: bool
        """
        
        # recursion
        def dfs(node):
            # recursion ending condition
            if(node == None):
                # empty node the height is 0
                return 0
            
            # post order traversal: left right middle
            leftHeight = dfs(node.left)
            # check left sub tree height return value is -1 or not
            if leftHeight == -1:
                # left sub tree is not blanaced binary tree
                return -1
            rightHeight = dfs(node.right)
            if rightHeight == -1:
                return -1
            
            # left and right both fit condtion of balanced binary tree, check height differencec
            result = 1
            if abs(rightHeight - leftHeight) > 1:
                # means it's not balance
                result = -1
            else:
                # mean's it balance; left and right sub tree max height + parent node height(+1)
                result  = 1+max(leftHeight,rightHeight)
            
            return result
        

        return False if dfs(root) == -1 else True

257. 二叉树的所有路径

1. 前序遍历:

   1. 这样才能让父节点指向孩子节点

2. 有递归一定会有回溯

   1. 回溯的过程就在递归函数的下面

3. 为什么会有回溯的过程?

   1. 一个容器来收集路径,如何把第一次路径获取的元素弹出,并收集新路径的元素,这个过程就叫做回溯

伪代码

``` c++
// 一个传节点,第一个数组用来传单条路径的,第二个数组用来返回最后答案
void travesal(node,vector<int>&path,vector<string>&result){
    // 添加遍历过的路径
    // 前序遍历的 中遍历(处理过程):
    // 把路径的节点添加进来
    // 这题有个例外;因为这题的终止条件是在叶子节点就结束了 
    // 如果这个卸载终止条件下面的话,我们就把最后一个叶子节点的值就落下了
    // 因为我们是到叶子节点就结束了,我们路径收集的节点在放在终止条件上面
    path.push_back(node->val);

    // 收集到叶子节点就结束没有必要到空节点
    if (node->left==null && node->right == null){
        //说明到叶子节点,说明到收集结果的时候
        result.push_back(path);
        return;
    }

    // 单层处理逻辑: 前序遍历 中左右

    // 左遍历: 判断一下节点不为空再去向左遍历,避免遇到空指针
    if(node->left){
        traversal(node->left,push,result);
        //回溯
        // 把第一次遇到的路径全部回退回去,直到根节点,这样才能收集另一条路径
        path.pop.back();
    }
    // 右: 逻辑跟左相同
    if(node->right){
        traversal(node->right,push,result);
        path.pop.back()
    }
    
}

可运行代码

# 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
class Solution(object):
    # recursion 
    def traversal(self,node,path,result):
        # middle 
        path.append(node.val) # save path element
        # recursion end, when left and right child are none
        if node.left == None and node.right == None:
            # mean's reach to the leaft node; collect this path
            sPath = '->'.join(map(str,path))    # convert each int type number to string by using -> connect
            result.append(sPath)    # save to final result set
            return 

        # pre order traversal
        # left
        # make sure is not empty pointer
        if node.left:
            self.traversal(node.left,path,result)
            # 回溯
            path.pop()
        if node.right:
            self.traversal(node.right,path,result)
            path.pop()
        
    def binaryTreePaths(self, root):
        """
        :type root: TreeNode
        :rtype: List[str]
        """
        # define two array, one is for collect path, other one is result set
        path = []
        result = []

        # if the node is empty
        if root == None:
            return result
        
        # call recursion
        self.traversal(root,path,result)

        return result

404.左叶子之和

1. 左叶子:

   1. 首先要是叶子;叶子节点就是左右孩子都为空成为叶子

   2. 一定是父节点的左孩子这样才是左叶子

2. 如何收集元素?

   1. 遍历到父元素之后;判断左孩子是否为空,同时左孩子的左右孩子都为空

   2. 那么当前遍历的节点左孩子就是要处理的数据

# 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
class Solution(object):
    def sumOfLeftLeaves(self, root):
        """
        :type root: TreeNode
        :rtype: int
        """
        
        # recursion end condtion
        if root == None:
            return 0
        
        # if we met leaf node is empty node
        if root.left == None and root.right == None:
            return 0
        
        # post order traversal
        leftNum = self.sumOfLeftLeaves(root.left) # left
        # makesure current left child is not empty,also the left child is left leaf(which is last node)
        if root.left != None and root.left.left == None and root.left.right == None:
            # cur parent node left leaf is our sum
            leftNum = root.left.val
        rightNum = self.sumOfLeftLeaves(root.right) # right

        # left sub tree + right sub tree sum
        sum_ = leftNum + rightNum

        return sum_

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

1. 除了底层节点,上面都是满的。底层节点是从左到右一字排开的(必须是连续的)

2. 遍历二叉树时其子树如果是满二叉树的话,可以直接用公式计算 2^深度次方-1

3. 根节点可以根据左右子树的数量+1就可以得到完全二叉树的节点数量

4. 如何判断子树是否是满二叉树?

   1. 如果是满二叉树,左右遍历的深度是相等的

   2. 如果子树不是满二叉树的情况的话,继续向下遍历

   3. 计算左右两侧外部深度,如果深度相同,说明是满二叉树

# 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
class Solution(object):
    def countNodes(self, root):
        """
        :type root: TreeNode
        :rtype: int
        """
        # end recursion condtion1
        if root == None:
            return 0
        
        # determine sub tree is complete Tree Node or not
        left = root.left
        right = root.right
        leftdepth = 1
        rightdepth = 1
        # check left side depth
        while left:
            left = left.left
            leftdepth += 1
        # check right side depth
        while right:
            right = right.right
            rightdepth += 1
        # if left side and right side depth are equal
        if leftdepth == rightdepth:
            # use formal calculate the node
            return (2 ** leftdepth) - 1
        
        # each recrusion logic
        # using post order traversal
        leftNum = self.countNodes(root.left)
        rightNum = self.countNodes(root.right)
        result = leftNum + rightNum + 1

        return result

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值