• 力扣刷题第二十八天--二叉树


    前言

    今天的五道题都是层序遍历的模板,深度优先的递归还不太熟。继续努力。

    内容

    一、在每个树行中找最大值

    515.在每个树行中找最大值

    给定一棵二叉树的根节点 root ,请找出该二叉树中每一层的最大值。

    广度优先搜素

    时间复杂度:O(n),其中 nnn 为二叉树节点个数,每一个节点仅会进出队列一次。

    空间复杂度:O(n),存储二叉树节点的空间开销。

    1. func largestValues(root *TreeNode) []int {
    2. var res []int
    3. if root==nil{
    4. return res
    5. }//没有这个会panic: runtime error: invalid memory address or nil pointer dereference
    6. curLevel:=[]*TreeNode{root}
    7. for len(curLevel)>0{
    8. nextLevel:=[]*TreeNode{}
    9. maxVal:=math.MinInt32
    10. for _,node:=range curLevel{
    11. maxVal= Max(maxVal,node.Val)
    12. if node.Left!=nil{
    13. nextLevel=append(nextLevel,node.Left)
    14. }
    15. if node.Right!=nil{
    16. nextLevel=append(nextLevel,node.Right)
    17. }
    18. }
    19. res=append(res,maxVal)
    20. curLevel=nextLevel
    21. }
    22. return res
    23. }
    24. func Max(a,b int)int{
    25. if a>b{
    26. return a
    27. }else{
    28. return b
    29. }
    30. }
    深度优先搜索

    时间复杂度:O(n),其中 nnn 为二叉树节点个数。二叉树的遍历中每个节点会被访问一次且只会被访问一次。

    空间复杂度:O(height)。其中 height 表示二叉树的高度。递归函数需要栈空间,而栈空间取决于递归的深度,因此空间复杂度等价于二叉树的高度。

    1. func largestValues(root *TreeNode)(ans []int){
    2. var dfs func(*TreeNode,int)
    3. dfs=func(node *TreeNode,height int){
    4. if node==nil{
    5. return
    6. }
    7. if height==len(ans){
    8. ans=append(ans,node.Val)
    9. }else{
    10. ans[height]=max(ans[height],node.Val)
    11. }
    12. dfs(node.Left,height+1)
    13. dfs(node.Right,height+1)
    14. }
    15. dfs(root,0)
    16. return
    17. }
    18. func max(a,b int)int{
    19. if a>b{
    20. return a
    21. }else{
    22. return b
    23. }
    24. }
    二、填充每个节点的下一个右侧节点指针

    116.填充每个节点的下一个右侧节点指针

    给定一个 完美二叉树 ,其所有叶子节点都在同一层,每个父节点都有两个子节点。二叉树定义如下:

    struct Node {
      int val;
      Node *left;
      Node *right;
      Node *next;
    }

    填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL

    初始状态下,所有 next 指针都被设置为 NULL

    广度优先搜素
    1. /**
    2. * Definition for a Node.
    3. * type Node struct {
    4. * Val int
    5. * Left *Node
    6. * Right *Node
    7. * Next *Node
    8. * }
    9. */
    10. func connect(root *Node) *Node {
    11. if root==nil{
    12. return root
    13. }
    14. curLevel:=[]*Node{root}
    15. for len(curLevel)>0{
    16. temp:=curLevel
    17. curLevel=nil
    18. for i,node:=range temp{
    19. if i+1<len(temp){
    20. node.Next=temp[i+1]
    21. }
    22. if node.Left!=nil{
    23. curLevel=append(curLevel,node.Left)
    24. }
    25. if node.Right!=nil{
    26. curLevel=append(curLevel,node.Right)
    27. }
    28. }
    29. }
    30. return root
    31. }
    使用已建立的next 指针 

    时间复杂度:O(N),每个节点只访问一次。

    空间复杂度:O(1),不需要存储额外的节点。

    1. func connect(root *Node)*Node{
    2. if root==nil{
    3. return root
    4. }
    5. // 每次循环从该层的最左侧节点开始
    6. for leftmost:=root;leftmost.Left!=nil;leftmost=leftmost.Left{
    7. // 通过 Next 遍历这一层节点,为下一层的节点更新 Next 指针
    8. for node:=leftmost;node!=nil;node=node.Next{
    9. // 左节点指向右节点
    10. node.Left.Next=node.Right
    11. if node.Next!=nil{
    12. // 右节点指向下一个左节点
    13. node.Right.Next=node.Next.Left
    14. }
    15. }
    16. }
    17. return root
    18. }
    三、填充每个节点的下一个右侧节点指针II

    117.填充每个节点的下一个右侧节点指针II

    给定一个二叉树:

    struct Node {
      int val;
      Node *left;
      Node *right;
      Node *next;
    }

    填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL 。

    初始状态下,所有 next 指针都被设置为 NULL 。

    广度优先搜素

    一模一样的代码 注意curLevel和temp 不要写混了

    1. func connect(root *Node) *Node {
    2. if root==nil{
    3. return root
    4. }
    5. curLevel:=[]*Node{root}
    6. for len(curLevel)>0{
    7. temp:=curLevel
    8. curLevel=nil
    9. for i,node:=range temp{
    10. if i+1<len(temp){
    11. node.Next=temp[i+1]
    12. }
    13. if node.Left!=nil{
    14. curLevel=append(curLevel,node.Left)
    15. }
    16. if node.Right!=nil{
    17. curLevel=append(curLevel,node.Right)
    18. }
    19. }
    20. }
    21. return root
    22. }
    四、二叉树的最大深度

    104.二叉树的最大深度

    给定一个二叉树 root ,返回其最大深度。

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

    广度优先搜素
    1. func maxDepth(root *TreeNode) int {
    2. var ans int
    3. if root==nil{
    4. return ans
    5. }
    6. curLevel:=[]*TreeNode{root}
    7. for len(curLevel)>0{
    8. temp:=curLevel
    9. curLevel=nil
    10. for _,node:=range temp{
    11. if node.Left!=nil{
    12. curLevel=append(curLevel,node.Left)
    13. }
    14. if node.Right!=nil{
    15. curLevel=append(curLevel,node.Right)
    16. }
    17. }
    18. ans++//记录深度,其他的是层序遍历的板子
    19. }
    20. return ans
    21. }
    深度优先搜索
    1. func maxDepth(root *TreeNode)int{
    2. if root==nil{
    3. return 0
    4. }
    5. return max(maxDepth(root.Left),maxDepth(root.Right))+1
    6. }
    7. func max(a,b int)int{
    8. if a>b{
    9. return a
    10. }
    11. return b
    12. }
    五、二叉树的最小深度

    111.二叉树的最小深度

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

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

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

    广度优先搜素
    1. func minDepth(root *TreeNode) int {
    2. var ans int
    3. if root==nil{
    4. return ans
    5. }
    6. curLevel:=[]*TreeNode{root}
    7. for len(curLevel)>0{
    8. temp:=curLevel
    9. curLevel=nil
    10. for _,node:=range temp{
    11. if node.Left==nil&&node.Right==nil{
    12. return ans+1
    13. }
    14. if node.Left!=nil{
    15. curLevel=append(curLevel,node.Left)
    16. }
    17. if node.Right!=nil{
    18. curLevel=append(curLevel,node.Right)
    19. }
    20. }
    21. ans++
    22. }
    23. return ans
    24. }
    深度优先搜索
    1. func minDepth(root *TreeNode)int{
    2. if root==nil{
    3. return 0
    4. }
    5. if root.Left==nil&&root.Right==nil{
    6. return 1
    7. }
    8. minD:=math.MaxInt32
    9. if root.Left!=nil{
    10. minD=min(minD,minDepth(root.Left))
    11. }
    12. if root.Right!=nil{
    13. minD=min(minD,minDepth(root.Right))
    14. }
    15. return minD+1
    16. }
    17. func min(a,b int)int{
    18. if a
    19. return a
    20. }
    21. return b
    22. }

    最后

    即使感知自己身体的需求,不管是体力消耗还是脑力消耗,及时补充能量,吃饭,休息。

  • 相关阅读:
    牛客 ( 计算几何
    什么是R语言?什么是R包?-R语言001
    MyBatis 的在使用上的注意事项及其辨析
    教程:如何使用 Bootstrap 5 构建简单的管理仪表板界面
    如果DAI遭遇攻击,加密世界会发生什么?
    免费旋转视频
    20天等待,申请终于通过,安装和体验IntelliJ IDEA新UI预览版
    TensorFlow 2.9的零零碎碎(一)
    Lakehouse 还是 Warehouse?(1/2)
    day 2 | 977.有序数组的平方 ,209.长度最小的子数组 ,59.螺旋矩阵II
  • 原文地址:https://blog.csdn.net/m0_62786673/article/details/134556918