首页 > 编程语言 >代码随想录算法训练营day15| 110.平衡二叉树 257.二叉树的所有路径 404.左叶子之和 222.完全二叉树的节点个数

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

时间:2024-10-14 21:49:12浏览次数:1  
标签:node right self 随想录 节点 二叉树 root 222 left

学习资料:https://programmercarl.com/0110.平衡二叉树.html#算法公开课

平衡二叉树:任意一个节点的左右子树高度差不超过1
左叶子:是叶子节点,且是其父节点的左节点
完全二叉树:上层均满,底层的节点从左到右连续
满二叉树:每层都是满的,节点总数为 (2^k + 1)
语法: 2<<1 是 2^2

学习记录:
110.平衡二叉树 (巧:当发现这个节点不平衡后,返回-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
        """
        node_height = self.getHeight(root)
        if node_height != -1:
            return True
        else:
            return False


    def getHeight(self, node):
        """
        递归法+后序遍历
        对于平衡二叉树而言,计算高度函数的逻辑是:
        当节点左右子树高度差超过1则该节点为不平衡,高度记为-1,则向上传递时,该节点作为上面的子树一直传递-1即可;
        而当节点左右子树高度不超过1,则记录节点的真实高度,即1+max(左右子树)
        """
        if not node:
            return 0
        left_h = self.getHeight(node.left)
        if left_h == -1:
            return -1
        right_h = self.getHeight(node.right)
        if right_h == -1:
            return -1
        if abs(left_h-right_h)>1:
            node_h = -1
        else:
            node_h = 1 + max(left_h, right_h)
        return node_h
        

257.二叉树的所有路径(递归+回溯)

点击查看代码
# 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 traversal(self, node, path, result):
        """
        前序遍历+回溯+递归
        """
        path.append(node.val)   # 存放当下考虑的节点,后面要弹出,相当于回到上一个节点
        if not node.left and not node.right:  # 叶子节点
            sPath = '->'.join(map(str, path))
            result.append(sPath)
            return
        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]
        """
        result = []
        path = []
        if not root:
            return result
        self.traversal(root, path, result)  # 因为list可以传递,traversal就不返回值了,只要处理list就行
        return result
        

404.左叶子之和(判断一个节点是否为左叶子,要在它的父节点处判断;后序遍历)

点击查看代码
# 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
        """
        # 如果节点是Null,那它没有左叶子
        if not root:
            return 0
        # 如果节点是叶子,那它没有左叶子
        if not root.left and not root.right:
            return 0
        
        # 那剩余情况的节点都有左叶子
        # 开始后序遍历,左右根,递归法
        # 左:节点的左子树中的左叶子的值
        left_num = self.sumOfLeftLeaves(root.left)     # 递归
        if root.left and not root.left.left and not root.left.right:   # 此节点root是判断它的左子节点root.left是否为左叶子(是叶子节点,且,为父节点的左子节点)
            left_num = root.left.val   # 提取左叶子的值
        
        # 右:节点的右子树的左叶子的值
        right_num = self.sumOfLeftLeaves(root.right)

        # 根:节点左子树的左叶子的值和右子树的左节点的值求和
        sum_num = left_num + right_num
        return sum_num
        

222.完全二叉树的节点个数(对于完全二叉树有个特殊解法,找到其中的满二叉树,那下面的直接2^k-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 countNodes(self, root):
        """
        :type root: TreeNode
        :rtype: int
        """
        # 后序遍历+递归法
        # 终止条件1:node为null
        if not root:
            return 0
        # 终止条件2:找到其中的满二叉树,这部分的节点数可用公式(2^k + 1)计算
        left = root.left
        right = root.right
        left_depth = 0
        right_depth = 0
        while left:              # 遍历root左子树的所有左节点
            left = left.left
            left_depth += 1
        while right:             # 遍历root右子树的所有右节点
            right = right.right
            right_depth += 1
        if left_depth == right_depth:      # 在完全二叉树的基础上,当左侧深度等于右侧深度,则此部分为满二叉树
            return (2 << left_depth) - 1    # 语法 2<<1是2^2,所以上面深度初始值记为0
        
        # 处理逻辑:后序,左右根
        left_num = self.countNodes(root.left)     # 当不是完全二叉树时,就向节点的左右子树递归,
        right_num = self.countNodes(root.right)
        total_num = left_num + right_num + 1
        return total_num 
            
        

PS:今天的有点费脑子,有点尝到递归的味道了,好像听懂了又好像没听懂,就感觉递归很方便
今天吃到了好吃的外卖,有锅气的土豆肉丝炒饭,和面泡软了的牛肉拉面
又是被审判的一次面试,是不是找不到工作了,我严重怀疑
勒!

标签:node,right,self,随想录,节点,二叉树,root,222,left
From: https://www.cnblogs.com/tristan241001/p/18466249

相关文章

  • 代码随想录算法训练营 | 121.买卖股票的最佳时机,122.买卖股票的最佳时机II,123.买卖股
    121.买卖股票的最佳时机题目链接:121.买卖股票的最佳时机文档讲解︰代码随想录(programmercarl.com)视频讲解︰买卖股票的最佳时机日期:2024-10-14想法:经常有用0和1表示相反状态,dp[i][0]表示第i天持有股票时身上最多的钱,比如第一天股票5元,持有了,身上的钱就为dp[0][0]=-5,第二天股......
  • 算法训练15-1判断平衡二叉树+二叉树的所有路径
    题目1:给定一个二叉树,判断它是否是 平衡二叉树  解法主要考察高度,后序遍历->需要递归法->递归法三步走/** *Definitionforabinarytreenode. *publicclassTreeNode{ *intval; *TreeNodeleft; *TreeNoderight; *TreeNode(){} *TreeNod......
  • 代码随想录算法训练营第三十四天|134. 加油站 135. 分发糖果 860.柠檬水找零 406.根据
    134.加油站在一条环路上有 N 个加油站,其中第 i 个加油站有汽油 gas[i] 升。你有一辆油箱容量无限的的汽车,从第i个加油站开往第i+1 个加油站需要消耗汽油 cost[i] 升。你从其中的一个加油站出发,开始时油箱为空。如果你可以绕环路行驶一周,则返回出发时加油站的......
  • 代码随想录算法训练营第三十二天|122.买卖股票的最佳时机 II 55. 跳跃游戏 45.跳跃游
    122.买卖股票的最佳时机II给定一个数组,它的第 i个元素是一支给定股票第i天的价格。设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。示例1:输入:[7,1,5......
  • 代码随想录算法训练营第三十一天|455.分发饼干 376. 摆动序列 53. 最大子序和
    455.分发饼干假设你是一位很棒的家长,想要给你的孩子们一些小饼干。但是,每个孩子最多只能给一块饼干。对每个孩子i,都有一个胃口值 g[i],这是能让孩子们满足胃口的饼干的最小尺寸;并且每块饼干j,都有一个尺寸s[j] 。如果s[j] >=g[i],我们可以将这个饼干j分配给孩子i,......
  • 代码随想录算法训练营第八天(1)|哈希表理论基础
    文档讲解:代码随想录难度:有一点哈希表理论基础哈希表首先什么是哈希表,哈希表(英文名字为Hashtable,国内也有一些算法书籍翻译为散列表,大家看到这两个名称知道都是指hashtable就可以了)。哈希表是根据关键码的值而直接进行访问的数据结构。这么官方的解释可能有点懵,其实......
  • 代码随想录2
    题目:移除元素:给你一个数组nums和一个值val,你需要原地移除所有数值等于val的元素,并返回移除后数组的新长度。不要使用额外的数组空间,你必须仅使用O(1)额外空间并原地修改输入数组。元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。示例1:给定nums=......
  • 代码随想录1
    一个简单的二分查找题。CPP代码。二分查找需要注意的地方就是区间的问题。如果是while(left<right)。就代表着区间定义是[left,right),即右边界取不到。因此当right缩小至middle时候只需要:while(left<right){...if(nums[middle]<target)right=middle;...}如果是两边并区间......
  • 代码随想录算法训练营 | 198.打家劫舍,213.打家劫舍II,337.打家劫舍III
    198.打家劫舍题目链接:198.打家劫舍文档讲解︰代码随想录(programmercarl.com)视频讲解︰打家劫舍日期:2024-10-13想法:dp[i]到第i个房子时能偷的最多的钱;递推公式:是上上一栋房子的dp[i-2]加上这栋房子的钱nums[i]大还是上一家邻居偷的钱dp[i-1]的大;初始化因为有i-2;所以初始化......
  • 【代码随想录Day41】动态规划Part10
    300.最长递增子序列题目链接/文章讲解:代码随想录视频讲解:动态规划之子序列问题,元素不连续!|LeetCode:300.最长递增子序列_哔哩哔哩_bilibilipublicintlengthOfLIS(int[]nums){//获取数组的长度intn=nums.length;//创建一个用于存储以每个元素结......