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

题目:

110. 平衡二叉树

给定一个二叉树,判断它是否是 

平衡二叉树

  

示例 1:

输入:root = [3,9,20,null,null,15,7]
输出:true

示例 2:

输入:root = [1,2,2,3,3,null,null,4,4]
输出:false

示例 3:

输入:root = []
输出:true

提示:

  • 树中的节点数在范围 [0, 5000] 内
  • -104 <= Node.val <= 104

思路:

1.求高度用后序遍历法,求深度用前序遍历法

2.终止条件 root==nil 返回0;递归返回值类型int,返回当前节点的高度

3.先求左子树相差的高度,再求右子树相差的高度,若其中有一个返回-1,则非平衡二叉树

4.若|左-右|(绝对值)<= -1, 则中间节点高度为1+max(l,r)

算法:

/**
 * Definition for a binary tree node.
 * type TreeNode struct {
 *     Val int
 *     Left *TreeNode
 *     Right *TreeNode
 * }
 */
func isBalanced(root *TreeNode) bool {
    h := getHigh(root)
    if h == -1 {
        return false
    } 
    return true
    

}

func getHigh(root *TreeNode) int {
    if root == nil {
        return 0
    }
    l_H := getHigh(root.Left)
    if l_H == -1 {
        return -1
    }
    r_H := getHigh(root.Right)
    if r_H == -1 {
        return -1
    }
    if l_H - r_H > 1 || r_H - l_H > 1 {
        return -1
    } 
        
    return 1 + max(l_H,r_H)
}

注意:

题目:

257. 二叉树的所有路径

给你一个二叉树的根节点 root ,按 任意顺序 ,返回所有从根节点到叶子节点的路径。

叶子节点 是指没有子节点的节点。

示例 1:

输入:root = [1,2,3,null,5]
输出:["1->2->5","1->3"]

示例 2:

输入:root = [1]
输出:["1"]

提示:

  • 树中节点的数目在范围 [1, 100] 内
  • -100 <= Node.val <= 100

思路:

1.遍历所有的路径,适合用前序遍历

2.终止条件:到叶子节点终止,注意叶子节点的判断

3.整数转字符串方法:strconv.Itoa()

算法:

/**
 * Definition for a binary tree node.
 * type TreeNode struct {
 *     Val int
 *     Left *TreeNode
 *     Right *TreeNode
 * }
 */
func binaryTreePaths(root *TreeNode) []string {
    sa :=  make([]string,0)
    var trees func(node *TreeNode, s string)
    trees = func(node *TreeNode, s string) {
        if node.Left == nil && node.Right == nil {
            s = s + strconv.Itoa(node.Val)
            sa = append(sa, s)
            return
        }
        s = s + strconv.Itoa(node.Val) + "->"
        if node.Left != nil {
            trees(node.Left, s)
        } 
        if node.Right != nil {
            trees(node.Right, s)
        } 
    }
    trees(root,"")
    return sa
}

注意:

题目:

404. 左叶子之和

给定二叉树的根节点 root ,返回所有左叶子之和。

示例 1:

输入: root = [3,9,20,null,null,15,7] 
输出: 24 
解释: 在这个二叉树中,有两个左叶子,分别是 9 和 15,所以返回 24

示例 2:

输入: root = [1]
输出: 0

提示:

  • 节点数在 [1, 1000] 范围内
  • -1000 <= Node.val <= 1000

思路:

1.关键在于左叶子节点的判断,父节点的左子节点存在,左子节点的左节点和右节点不存在,该子节点为左叶子节点

算法:

/**
 * Definition for a binary tree node.
 * type TreeNode struct {
 *     Val int
 *     Left *TreeNode
 *     Right *TreeNode
 * }
 */
func sumOfLeftLeaves(root *TreeNode) int {
    if root == nil {
        return 0
    }

    l := sumOfLeftLeaves(root.Left) //左
    r := sumOfLeftLeaves(root.Right) //右
    //中 判断左叶子节点
    if root.Left != nil && root.Left.Left == nil && root.Left.Right == nil {
        l = root.Left.Val
    }
    return l + r

}

注意:

题目:

513. 找树左下角的值

给定一个二叉树的 根节点 root,请找出该二叉树的 最底层 最左边 节点的值。

假设二叉树中至少有一个节点。

示例 1:

输入: root = [2,1,3]
输出: 1

示例 2:

输入: [1,2,3,4,null,5,6,null,null,7]
输出: 7

提示:

  • 二叉树的节点个数的范围是 [1,104]
  • -231 <= Node.val <= 231 - 1 

思路:

1.采用层序遍历,返回层序遍历的第一个元素即可

算法:

/**
 * Definition for a binary tree node.
 * type TreeNode struct {
 *     Val int
 *     Left *TreeNode
 *     Right *TreeNode
 * }
 */
func findBottomLeftValue(root *TreeNode) int {
    //层序遍历,返回最后一层的第一个元素即可
     arr := make([][]int, 0)
     if root == nil {
        return 0
     } 
     tmp := make([]int,0)
     que := list.New()
     que.PushBack(root)
     for que.Len() != 0 {
        size := que.Len()
        for i := 0; i < size; i++ {
            node := que.Remove(que.Front()).(*TreeNode)
            if node.Left != nil {
                que.PushBack(node.Left)
            }
            if node.Right != nil {
                que.PushBack(node.Right)
            }
            tmp = append(tmp, node.Val)
        }
        arr = append(arr,tmp)
        tmp = []int{}
     }
     return arr[len(arr)-1][0]
}

注意:

1.每次tmp压入arr后,需要清空tmp,重新计算

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值