代码随想录算法训练营day15| 层序遍历 226.翻转二叉树

层序遍历 

102.二叉树的层序遍历

type TreeNode struct {
	Val   int
	Left  *TreeNode
	Right *TreeNode
}
type Queue struct {
	queue []*TreeNode
}

func (q *Queue) Size() int {
	return len(q.queue)
}
func (q *Queue) Empty() bool {
	return q.Size() == 0
}
func (q *Queue) Enqueue(n *TreeNode) {
	q.queue = append(q.queue, n)
}
func (q *Queue) Front() *TreeNode {
	return q.queue[0]
}
func (q *Queue) Dequeue() *TreeNode {
	front := q.Front()
	q.queue = q.queue[1:]
	return front
}
func levelOrder(root *TreeNode) [][]int {
	// 层序遍历基本操作,使用一个队列来辅助,先存根节点,每次弹出一个节点都将子节点加入队列中,注意计算每层的节点数
	result := make([][]int, 0)
	queue := Queue{}
	if root == nil {
		return result
	}
	queue.Enqueue(root)  // 根节点先入队
	for !queue.Empty() { // 当还有节点时
		nodeNum := queue.Size()
		levelResult := make([]int, 0)
		for i := 0; i < nodeNum; i++ {
			front := queue.Dequeue()
			if front.Left != nil {
				queue.Enqueue(front.Left)
			}
			if front.Right != nil {
				queue.Enqueue(front.Right)
			}
			levelResult = append(levelResult, front.Val)
		}
		result = append(result, levelResult)
	}
	return result
}

107.二叉树的层次遍历 II

 在上题的基础上将结果反转即可,反转切片使用双指针法

type TreeNode struct {
	Val   int
	Left  *TreeNode
	Right *TreeNode
}
type Queue struct {
	queue []*TreeNode
}

func (q *Queue) Size() int {
	return len(q.queue)
}
func (q *Queue) Empty() bool {
	return q.Size() == 0
}
func (q *Queue) Enqueue(n *TreeNode) {
	q.queue = append(q.queue, n)
}
func (q *Queue) Front() *TreeNode {
	return q.queue[0]
}
func (q *Queue) Dequeue() *TreeNode {
	front := q.Front()
	q.queue = q.queue[1:]
	return front
}
func reverseSlice(s [][]int) {
	left, right := 0, len(s)-1 // 双指针反转切片
	for left < right {
		s[left], s[right] = s[right], s[left]
		left++
		right--
	}
}
func levelOrderBottom(root *TreeNode) [][]int {
	// 层序遍历基本操作,使用一个队列来辅助,先存根节点,每次弹出一个节点都将子节点加入队列中,注意计算每层的节点数
	result := make([][]int, 0)
	queue := Queue{}
	if root == nil {
		return result
	}
	queue.Enqueue(root)  // 根节点先入队
	for !queue.Empty() { // 当还有节点时
		nodeNum := queue.Size()
		levelResult := make([]int, 0)
		for i := 0; i < nodeNum; i++ {
			front := queue.Dequeue()
			if front.Left != nil {
				queue.Enqueue(front.Left)
			}
			if front.Right != nil {
				queue.Enqueue(front.Right)
			}
			levelResult = append(levelResult, front.Val)
		}
		result = append(result, levelResult)
	}
	reverseSlice(result)
	return result
}

199.二叉树的右视图

层序遍历后获取每层最右边的元素即可

type TreeNode struct {
	Val   int
	Left  *TreeNode
	Right *TreeNode
}
type Queue struct {
	queue []*TreeNode
}

func (q *Queue) Size() int {
	return len(q.queue)
}
func (q *Queue) Empty() bool {
	return q.Size() == 0
}
func (q *Queue) Enqueue(n *TreeNode) {
	q.queue = append(q.queue, n)
}
func (q *Queue) Front() *TreeNode {
	return q.queue[0]
}
func (q *Queue) Dequeue() *TreeNode {
	front := q.Front()
	q.queue = q.queue[1:]
	return front
}

func rightSideView(root *TreeNode) []int {
	// 获取每层最右侧的元素即可
	queue := &Queue{}
	result := make([]int, 0)
	if root == nil {
		return result
	}
	queue.Enqueue(root)
	for !queue.Empty() {
		numLevel := queue.Size()
		var front *TreeNode
		for i := 0; i < numLevel; i++ {
			front = queue.Dequeue()
			if front.Left != nil {
				queue.Enqueue(front.Left)
			}
			if front.Right != nil {
				queue.Enqueue(front.Right)
			}
		}
		result = append(result, front.Val)
	}
	return result
}

637.二叉树的层平均值 

层序遍历后,对每层的元素求和即可

type TreeNode struct {
	Val   int
	Left  *TreeNode
	Right *TreeNode
}
type Queue struct {
	queue []*TreeNode
}

func (q *Queue) Size() int {
	return len(q.queue)
}
func (q *Queue) Empty() bool {
	return q.Size() == 0
}
func (q *Queue) Enqueue(n *TreeNode) {
	q.queue = append(q.queue, n)
}
func (q *Queue) Front() *TreeNode {
	return q.queue[0]
}
func (q *Queue) Dequeue() *TreeNode {
	front := q.Front()
	q.queue = q.queue[1:]
	return front
}

func averageOfLevels(root *TreeNode) []float64 {
	// 每层元素求和取均值即可
	queue := &Queue{}
	result := make([]float64, 0)
	if root == nil {
		return result
	}
	queue.Enqueue(root)
	for !queue.Empty() {
		numLevel := queue.Size()
		sum := 0.0
		for i := 0; i < numLevel; i++ {
			front := queue.Dequeue()
			sum += float64(front.Val)
			if front.Left != nil {
				queue.Enqueue(front.Left)
			}
			if front.Right != nil {
				queue.Enqueue(front.Right)
			}
		}
		result = append(result, sum/float64(numLevel))
	}
	return result
}

429.N叉树的层序遍历

同理,将原来的遍历两个节点变成遍历n个节点

type Node struct {
	Val      int
	Children []*Node
}
type Queue struct {
	queue []*Node
}

func (q *Queue) Size() int {
	return len(q.queue)
}
func (q *Queue) Empty() bool {
	return q.Size() == 0
}
func (q *Queue) Enqueue(n *Node) {
	q.queue = append(q.queue, n)
}
func (q *Queue) Front() *Node {
	return q.queue[0]
}
func (q *Queue) Dequeue() *Node {
	front := q.Front()
	q.queue = q.queue[1:]
	return front
}

func levelOrder(root *Node) [][]int {
	queue := &Queue{}
	result := make([][]int, 0)
	if root == nil {
		return result
	}
	queue.Enqueue(root)
	for !queue.Empty() {
		numLevel := queue.Size()
		resultLevel := make([]int, 0)
		for i := 0; i < numLevel; i++ {
			front := queue.Dequeue()
			resultLevel = append(resultLevel, front.Val)
			for _, child := range front.Children {
				queue.Enqueue(child)
			}
		}
		result = append(result, resultLevel)
	}
	return result
}

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

层序遍历,记录最大值即可

type TreeNode struct {
	Val   int
	Left  *TreeNode
	Right *TreeNode
}

type Queue struct {
	queue []*TreeNode
}

func (q *Queue) Size() int {
	return len(q.queue)
}
func (q *Queue) Empty() bool {
	return q.Size() == 0
}
func (q *Queue) Enqueue(n *TreeNode) {
	q.queue = append(q.queue, n)
}
func (q *Queue) Front() *TreeNode {
	return q.queue[0]
}
func (q *Queue) Dequeue() *TreeNode {
	front := q.Front()
	q.queue = q.queue[1:]
	return front
}
func largestValues(root *TreeNode) []int {
	queue := new(Queue)
	result := make([]int, 0)
	if root == nil {
		return result
	}
	queue.Enqueue(root)
	for !queue.Empty() {
		numLevel := queue.Size()
		maxVal := queue.Front().Val
		for i := 0; i < numLevel; i++ {
			front := queue.Dequeue()
			if front.Val > maxVal {
				maxVal = front.Val
			}
			if front.Left != nil {
				queue.Enqueue(front.Left)
			}
			if front.Right != nil {
				queue.Enqueue(front.Right)
			}
		}
		result = append(result, maxVal)
	}
	return result
}

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

层序遍历,将每个弹出的元素的next指向队列中的front元素,并将每层最后一个元素指向nil

type Node struct {
	Val   int
	Left  *Node
	Right *Node
	Next  *Node
}
type Queue struct {
	queue []*Node
}

func (q *Queue) Size() int {
	return len(q.queue)
}
func (q *Queue) Empty() bool {
	return q.Size() == 0
}
func (q *Queue) Enqueue(n *Node) {
	q.queue = append(q.queue, n)
}
func (q *Queue) Front() *Node {
	if q.Empty() {
		return nil
	}
	return q.queue[0]
}
func (q *Queue) Dequeue() *Node {
	front := q.Front()
	q.queue = q.queue[1:]
	return front
}
func connect(root *Node) *Node {
	// 层序遍历,当每层的最后一个赋为nil
	if root == nil {
		return root
	}
	queue := new(Queue)
	queue.Enqueue(root)
	for !queue.Empty() {
		numLevel := queue.Size()
		for i := 0; i < numLevel; i++ {
			front := queue.Dequeue()
			front.Next = queue.Front()
			if i == numLevel-1 {
				front.Next = nil
			}
			if front.Left != nil {
				queue.Enqueue(front.Left)
			}
			if front.Right != nil {
				queue.Enqueue(front.Right)
			}
		}
	}
	return root
}

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

和上一题完全相同的代码,啥都不用改(上一题为本体的特例)

104.二叉树的最大深度

层序遍历,记录深度即可

type Node struct {
	Val   int
	Left  *Node
	Right *Node
	Next  *Node
}
type Queue struct {
	queue []*TreeNode
}

func (q *Queue) Size() int {
	return len(q.queue)
}
func (q *Queue) Empty() bool {
	return q.Size() == 0
}
func (q *Queue) Enqueue(n *TreeNode) {
	q.queue = append(q.queue, n)
}
func (q *Queue) Front() *TreeNode {
	if q.Empty() {
		return nil
	}
	return q.queue[0]
}
func (q *Queue) Dequeue() *TreeNode {
	front := q.Front()
	q.queue = q.queue[1:]
	return front
}
func maxDepth(root *TreeNode) int {
	// 层序遍历,记录深度即可
	depth := 0
	if root == nil {
		return depth
	}
	queue := new(Queue)
	queue.Enqueue(root)
	for !queue.Empty() {
		numLevel := queue.Size()
		depth++
		for i := 0; i < numLevel; i++ {
			front := queue.Dequeue()
			if front.Left != nil {
				queue.Enqueue(front.Left)
			}
			if front.Right != nil {
				queue.Enqueue(front.Right)
			}
		}
	}
	return depth
}

111.二叉树的最小深度

层序遍历,遇到叶子节点(左右子节点均为空)时即返回当前的depth

type TreeNode struct {
	Val   int
	Left  *TreeNode
	Right *TreeNode
}
type Queue struct {
	queue []*TreeNode
}

func (q *Queue) Size() int {
	return len(q.queue)
}
func (q *Queue) Empty() bool {
	return q.Size() == 0
}
func (q *Queue) Enqueue(n *TreeNode) {
	q.queue = append(q.queue, n)
}
func (q *Queue) Front() *TreeNode {
	if q.Empty() {
		return nil
	}
	return q.queue[0]
}
func (q *Queue) Dequeue() *TreeNode {
	front := q.Front()
	q.queue = q.queue[1:]
	return front
}
func minDepth(root *TreeNode) int {
	// 层序遍历,记录深度即可
	depth := 0
	if root == nil {
		return depth
	}
	queue := new(Queue)
	queue.Enqueue(root)
	for !queue.Empty() {
		numLevel := queue.Size()
		depth++
		for i := 0; i < numLevel; i++ {
			front := queue.Dequeue()
			if front.Right == nil && front.Left == nil {
				return depth
			}
			if front.Left != nil {
				queue.Enqueue(front.Left)
			}
			if front.Right != nil {
				queue.Enqueue(front.Right)
			}
		}
	}
	return depth
}

226.翻转二叉树

法一:深度优先搜索

使用递归深搜遍历的方式

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

func dfs(root *TreeNode) {
	// 将每个节点的子节点交换
	if root == nil {
		return
	}
	root.Left, root.Right = root.Right, root.Left // 交换节点
	dfs(root.Left)
	dfs(root.Right)
}
func invertTree(root *TreeNode) *TreeNode {
	// 法一:深搜
	dfs(root)
	return root
}

法二:层序遍历(广度优先搜索)

层序遍历,遇到节点就翻转

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

type Queue struct {
	queue []*TreeNode
}

func (q *Queue) Size() int {
	return len(q.queue)
}
func (q *Queue) Empty() bool {
	return q.Size() == 0
}
func (q *Queue) Enqueue(n *TreeNode) {
	q.queue = append(q.queue, n)
}
func (q *Queue) Front() *TreeNode {
	if q.Empty() {
		return nil
	}
	return q.queue[0]
}
func (q *Queue) Dequeue() *TreeNode {
	front := q.Front()
	q.queue = q.queue[1:]
	return front
}

func invertTree(root *TreeNode) *TreeNode {
	// 法二:层序遍历
	if root == nil {
		return nil
	}
	queue := new(Queue)
	queue.Enqueue(root)
	for !queue.Empty() {
		numLevel := queue.Size()
		for i := 0; i < numLevel; i++ {
			front := queue.Dequeue()
			front.Left, front.Right = front.Right, front.Left // 反转
			if front.Left != nil {
				queue.Enqueue(front.Left)
			}
			if front.Right != nil {
				queue.Enqueue(front.Right)
			}
		}
	}
	return root
}

101. 对称二叉树

法一(迭代): 层次遍历反转二叉树,判断反转后是否与原来相同即可

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

type Queue struct {
	queue []*TreeNode
}

func (q *Queue) Size() int {
	return len(q.queue)
}
func (q *Queue) Empty() bool {
	return q.Size() == 0
}
func (q *Queue) Enqueue(n *TreeNode) {
	q.queue = append(q.queue, n)
}
func (q *Queue) Front() *TreeNode {
	if q.Empty() {
		return nil
	}
	return q.queue[0]
}
func (q *Queue) Dequeue() *TreeNode {
	front := q.Front()
	q.queue = q.queue[1:]
	return front
}

func copyTree(dst *TreeNode, src *TreeNode) {
	var dfsSrc func(dst *TreeNode, src *TreeNode)
	dfsSrc = func(dst *TreeNode, src *TreeNode) {
		if src == nil {
			return
		}
		if src.Left != nil {
			dst.Left = &TreeNode{Val: src.Left.Val, Left: nil, Right: nil}
		}
		if src.Right != nil {
			dst.Right = &TreeNode{Val: src.Right.Val, Left: nil, Right: nil}
		}
		dfsSrc(dst.Left, src.Left)
		dfsSrc(dst.Right, src.Right)
	}
    dst.Val = src.Val
	dfsSrc(dst, src)
}
func compTree(left *TreeNode, right *TreeNode) bool {
	if left != nil && right != nil {
		if left.Val == right.Val {
			return compTree(left.Left, right.Left) && compTree(left.Right, right.Right)
		} else {
			return false
		}
	}
	if left == nil && right == nil {
		return true
	}
	return false
}
func isSymmetric(root *TreeNode) bool {
	//法一(迭代): 层次遍历反转二叉树,判断反转后是否与原来相同即可
	newNode := new(TreeNode)
	copyTree(newNode, root)
	queue := new(Queue)
	queue.Enqueue(newNode)
	for !queue.Empty() {
		numLevel := queue.Size()
		for i := 0; i < numLevel; i++ {
			front := queue.Dequeue()
			front.Left, front.Right = front.Right, front.Left // 反转
			if front.Left != nil {
				queue.Enqueue(front.Left)
			}
			if front.Right != nil {
				queue.Enqueue(front.Right)
			}
		}
	}
	return compTree(root, newNode)
}

法二(递归):沿着对称的路线遍历

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

func leftSearch(root *TreeNode, res *[]*TreeNode) {
	*res = append(*res, root)
	if root == nil {
		return
	}
	leftSearch(root.Left, res)
	leftSearch(root.Right, res)
}
func rightSearch(root *TreeNode, res *[]*TreeNode) {
	*res = append(*res, root)
	if root == nil {
		return
	}
	rightSearch(root.Right, res)
	rightSearch(root.Left, res)
}
func isSymmetric(root *TreeNode) bool {
	resLeft := make([]*TreeNode, 0)
	resRight := make([]*TreeNode, 0)
	leftSearch(root.Left, &resLeft)
	rightSearch(root.Right, &resRight)
	if len(resLeft) != len(resRight) {
		return false
	}
	for i := 0; i < len(resLeft); i++ {
		if resLeft[i] == nil && resRight[i] == nil {
			continue
		}
		if resLeft[i] != nil && resRight[i] != nil {
			if resLeft[i].Val != resRight[i].Val {
				return false
			}
		} else {
			return false
		}
	}
	return true
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值