层序遍历
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
}