[Go版]算法通关村——树的层序遍历

目录

  • 二叉树的层序遍历
    • 思路:队列缓存每层节点
    • 复杂度:时间复杂度 O ( n ) O(n) O(n)、空间复杂度 O ( n ) O(n) O(n)
  • 题目:二叉树的层序遍历
    • 思路分析:队列缓存
    • Go代码
  • 题目:二叉树的层序遍历||
    • 思路分析:队列缓存+反转输出
    • Go代码
  • 题目:二叉树的右视图
    • 思路分析:队列缓存+输出每层最后一个节点值
    • Go代码
  • 题目:二叉树的层平均值
    • 思路分析:队列缓存+输出每层节点值的平均值
    • Go代码
  • 题目:N叉树的层序遍历
    • 思路分析:队列缓存+遍历所有Children节点
    • Go代码
  • 题目:在每个树行中找最大值
    • 思路分析:队列缓存+输出每行节点值中的最大值
    • Go代码
  • 题目:填充每个节点的下一个右侧节点指针
    • 思路分析:队列缓存+每行节点依次指向自己的下一个
    • Go代码
  • 题目:二叉树的锯齿形层序遍历
    • 思路分析:队列缓存+输出时区分奇偶行
    • Go代码

二叉树的层序遍历

二叉树的层序遍历:就是从根节点root开始,从上到下,从左到右,依次遍历到每个子节点。

层序遍历的这类题目,一般都是要求返回特定的每层节点数组,其中每层可能是所有节点树、最大的节点数、最小的节点数、所有节点数的平均数、正序输出显示、逆序输出显示、每层第一个节点数、每层最后一个节点数等等

思路:队列缓存每层节点

  1. 因为要获取到每层节点,并且需要单独处理每层节点,所以可以使用队列来缓存每层节点。
  2. 做一个for循环,让队列里始终有一层的结点元素等待被依次取出进行操作。
  3. 然后每取出一个节点就将该节点的子节点都进入到队列中,这样当队列中当前层节点都取出完毕后,下一层的所有节点已经全部进入队列中。
  4. 如此循环,直至最后一层被取完即可。

复杂度:时间复杂度 O ( n ) O(n) O(n)、空间复杂度 O ( n ) O(n) O(n)

题目:二叉树的层序遍历

题目链接:LeetCode-102. 二叉树的层序遍历
[Go版]算法通关村——树的层序遍历_第1张图片

思路分析:队列缓存

Go代码

func levelOrder(root *TreeNode) [][]int {
    if root == nil {
        return nil
    }
    ret_arr := make([][]int, 0)
    // 缓存队列
    queue := []*TreeNode{root}
    for len(queue) != 0 {
        length := len(queue)
        arr := make([]int, 0)
        for i:=0;i<length;i++ {
            // 取出队列中所有树节点的值(同一层的)
            arr = append(arr, queue[i].Val)
            // 将对应节点如果有左右子节点就加入到队列中
            if queue[i].Left != nil {
                queue = append(queue, queue[i].Left)
            }
            if queue[i].Right != nil {
                queue = append(queue, queue[i].Right)
            }
        }
        // 从队列中删除已取过值的树节点
        queue = queue[length:]
        ret_arr = append(ret_arr, arr)
    }
    return ret_arr
}

题目:二叉树的层序遍历||

题目链接:LeetCode-107. 二叉树的层序遍历 II
[Go版]算法通关村——树的层序遍历_第2张图片

思路分析:队列缓存+反转输出

Go代码

func reverseArr(arr [][]int, left int, right int) {
    for left<= right {
        arr[left], arr[right] = arr[right], arr[left]
        left++
        right--
    }
}
func levelOrderBottom(root *TreeNode) [][]int {
    if root == nil {
        return nil
    }
    ret_arr := make([][]int, 0)
    queue := []*TreeNode{root}
    for len(queue) != 0 {
        arr := make([]int, 0)
        length := len(queue)
        for i:=0; i<length; i++ {
            arr = append(arr, queue[i].Val)
            if queue[i].Left != nil {
                queue = append(queue, queue[i].Left)
            }
            if queue[i].Right != nil {
                queue = append(queue, queue[i].Right)
            }
        }
        queue = queue[length:]
        ret_arr = append(ret_arr, arr)
    }
    reverseArr(ret_arr, 0, len(ret_arr)-1)
    return ret_arr
}

题目:二叉树的右视图

题目链接:LeetCode-199. 二叉树的右视图
[Go版]算法通关村——树的层序遍历_第3张图片

思路分析:队列缓存+输出每层最后一个节点值

Go代码

func rightSideView(root *TreeNode) []int {
    if root == nil {
        return nil
    }
    ret_arr := make([]int, 0)
    queue := []*TreeNode{root}
    for len(queue) != 0 {
        length := len(queue)
        ret_arr = append(ret_arr, queue[length-1].Val)
        for i:=0;i<length;i++ {
            if queue[i].Left != nil {
                queue = append(queue, queue[i].Left)
            }
            if queue[i].Right != nil {
                queue = append(queue, queue[i].Right)
            }
        }
        queue = queue[length:]
    }
    return ret_arr
}

题目:二叉树的层平均值

题目链接:LeetCode-637. 二叉树的层平均值
[Go版]算法通关村——树的层序遍历_第4张图片

思路分析:队列缓存+输出每层节点值的平均值

Go代码

func averageOfLevels(root *TreeNode) []float64 {
    if root == nil {
        return nil
    }
    ret_arr := make([]float64, 0)
    queue := []*TreeNode{root}
    for len(queue) != 0 {
        sum := 0
        length := len(queue)
        for i:=0; i<length; i++ {
            sum += queue[i].Val
            if queue[i].Left != nil {
                queue = append(queue, queue[i].Left)
            }
            if queue[i].Right != nil {
                queue = append(queue, queue[i].Right)
            }
        }
        queue = queue[length:]
        ret_arr = append(ret_arr, float64(sum)/float64(length))
    }
    return ret_arr
}

题目:N叉树的层序遍历

题目链接:LeetCode-429. N 叉树的层序遍历
[Go版]算法通关村——树的层序遍历_第5张图片

思路分析:队列缓存+遍历所有Children节点

Go代码

func levelOrder(root *Node) [][]int {
    if root == nil {
        return nil
    }
    ret_arr := make([][]int, 0)
    queue := []*Node{root}
    for len(queue)!= 0 {
        arr := make([]int, 0)
        length := len(queue)
        for i:=0; i<length; i++ {
            arr = append(arr, queue[i].Val)
            for j:=0; j<len(queue[i].Children); j++ {
                queue = append(queue, queue[i].Children[j])
            }
        }
        queue = queue[length:]
        ret_arr = append(ret_arr, arr)
    }
    return ret_arr
}

题目:在每个树行中找最大值

题目链接:LeetCode-515. 在每个树行中找最大值
[Go版]算法通关村——树的层序遍历_第6张图片

思路分析:队列缓存+输出每行节点值中的最大值

Go代码

func largestValues(root *TreeNode) []int {
    if root == nil {
        return nil
    }
    ret_arr := make([]int, 0)
    queue := []*TreeNode{root}
    for len(queue) != 0 {
        max := queue[0].Val
        length := len(queue)
        for i:=0;i<length;i++{
            if max < queue[i].Val {
                max = queue[i].Val
            }
            if queue[i].Left != nil {
                queue = append(queue, queue[i].Left)
            }
            if queue[i].Right != nil {
                queue = append(queue, queue[i].Right)
            }
        }
        queue = queue[length:]
        ret_arr = append(ret_arr, max)
    }
    return ret_arr
}

题目:填充每个节点的下一个右侧节点指针

题目链接:LeetCode-116. 填充每个节点的下一个右侧节点指针
[Go版]算法通关村——树的层序遍历_第7张图片

思路分析:队列缓存+每行节点依次指向自己的下一个

Go代码

func connect(root *Node) *Node {
	if root == nil  {
        return root
    }
    queue := []*Node{root}
    for len(queue) != 0 {
        length := len(queue)
        for i:=0;i<length;i++ {
            if i!= length-1 {
                queue[i].Next = queue[i+1]
            }
            if queue[i].Left != nil {
                queue = append(queue, queue[i].Left)
            }
            if queue[i].Right != nil {
                queue = append(queue, queue[i].Right)
            }
        }
        queue = queue[length:]
    }
    return root
}

题目:二叉树的锯齿形层序遍历

题目链接:LeetCode-103. 二叉树的锯齿形层序遍历
[Go版]算法通关村——树的层序遍历_第8张图片

思路分析:队列缓存+输出时区分奇偶行

Go代码

func reverseArr(arr []int, left int, right int) {
    for left<=right {
        arr[left], arr[right] = arr[right], arr[left]
        left++
        right--
    }
}
func zigzagLevelOrder(root *TreeNode) [][]int {
    if root == nil {
        return nil
    }
    ret_arr := make([][]int, 0)
    queue := []*TreeNode{root}
    odd := true
    for len(queue) != 0 {
        length := len(queue)
        arr := make([]int, 0)
        for i:=0;i<length;i++ {
            arr = append(arr, queue[i].Val)
            if queue[i].Left != nil {
                queue = append(queue, queue[i].Left)
            }
            if queue[i].Right != nil {
                queue = append(queue, queue[i].Right)
            }
        }
        queue = queue[length:]
        if !odd {
            reverseArr(arr, 0, len(arr)-1)
        }
        odd = !odd
        ret_arr = append(ret_arr, arr)
    }
    return ret_arr
}

你可能感兴趣的:(算法与数据结构,golang,算法)