Golang每日一练(leetDay0035) 二叉树专题(4)

简介: Golang每日一练(leetDay0035) 二叉树专题(4)

二叉树专题(4)


103. 二叉树的锯齿形层序遍历 Binary Tree Zigzag Level Order Traversal


给你二叉树的根节点 root ,返回其节点值的 锯齿形层序遍历 。(即先从左往右,再从右往左进行下一层遍历,以此类推,层与层之间交替进行)。


示例 1:

efe93506f62884d8de17bddea606d644.jpeg



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

输出:[[3],[20,9],[15,7]]


示例 2:

输入:root = [1]

输出:[[1]]


示例 3:

输入:root = []

输出:[]


提示:

   树中节点数目在范围 [0, 2000] 内

   -100 <= Node.val <= 100


代码1: 递归


package main
import (
  "fmt"
)
const null = -1 << 31
type TreeNode struct {
  Val   int
  Left  *TreeNode
  Right *TreeNode
}
func zigzagLevelOrder(root *TreeNode) [][]int {
  res := [][]int{}
  dfs(root, 0, &res)
  return res
}
func dfs(node *TreeNode, level int, res *[][]int) {
  if node == nil {
    return
  }
  if len(*res) <= level {
    *res = append(*res, []int{})
  }
  if level%2 == 0 {
    (*res)[level] = append((*res)[level], node.Val)
  } else {
    (*res)[level] = append([]int{node.Val}, (*res)[level]...)
  }
  dfs(node.Left, level+1, res)
  dfs(node.Right, level+1, res)
}
func buildTree(nums []int) *TreeNode {
  if len(nums) == 0 {
    return nil
  }
  root := &TreeNode{Val: nums[0]}
  Queue := []*TreeNode{root}
  idx := 1
  for idx < len(nums) {
    node := Queue[0]
    Queue = Queue[1:]
    if nums[idx] != null {
      node.Left = &TreeNode{Val: nums[idx]}
      Queue = append(Queue, node.Left)
    }
    idx++
    if idx < len(nums) && nums[idx] != null {
      node.Right = &TreeNode{Val: nums[idx]}
      Queue = append(Queue, node.Right)
    }
    idx++
  }
  return root
}
func main() {
  nums := []int{3, 9, 20, null, null, 15, 7}
  root := buildTree(nums)
  fmt.Println(zigzagLevelOrder(root))
}

代码2: 迭代

package main
import (
  "fmt"
)
const null = -1 << 31
type TreeNode struct {
  Val   int
  Left  *TreeNode
  Right *TreeNode
}
func zigzagLevelOrder(root *TreeNode) [][]int {
  if root == nil {
    return [][]int{}
  }
  res := [][]int{}
  queue := []*TreeNode{root}
  level := 0
  for len(queue) > 0 {
    size := len(queue)
    levelRes := []int{}
    stack := []*TreeNode{}
    for i := 0; i < size; i++ {
      node := queue[0]
      queue = queue[1:]
      levelRes = append(levelRes, node.Val)
      if level%2 == 0 {
        if node.Left != nil {
          stack = append(stack, node.Left)
        }
        if node.Right != nil {
          stack = append(stack, node.Right)
        }
      } else {
        if node.Right != nil {
          stack = append(stack, node.Right)
        }
        if node.Left != nil {
          stack = append(stack, node.Left)
        }
      }
    }
    for i := len(stack) - 1; i >= 0; i-- {
      queue = append(queue, stack[i])
    }
    res = append(res, levelRes)
    level++
  }
  return res
}
func buildTree(nums []int) *TreeNode {
  if len(nums) == 0 {
    return nil
  }
  root := &TreeNode{Val: nums[0]}
  Queue := []*TreeNode{root}
  idx := 1
  for idx < len(nums) {
    node := Queue[0]
    Queue = Queue[1:]
    if nums[idx] != null {
      node.Left = &TreeNode{Val: nums[idx]}
      Queue = append(Queue, node.Left)
    }
    idx++
    if idx < len(nums) && nums[idx] != null {
      node.Right = &TreeNode{Val: nums[idx]}
      Queue = append(Queue, node.Right)
    }
    idx++
  }
  return root
}
func main() {
  nums := []int{3, 9, 20, null, null, 15, 7}
  root := buildTree(nums)
  fmt.Println(zigzagLevelOrder(root))
}

输出:

[[3] [20 9] [15 7]]


104. 二叉树的最大深度 Maximum Depth of Binary-tree]


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

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


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


示例:

给定二叉树 [3,9,20,null,null,15,7],

   3

  / \

 9  20

   /  \

  15   7

返回它的最大深度 3 。


代码1: 递归

package main
import (
  "fmt"
)
const null = -1 << 31
type TreeNode struct {
  Val   int
  Left  *TreeNode
  Right *TreeNode
}
func maxDepth(root *TreeNode) int {
  if root == nil {
    return 0
  }
  leftDepth := maxDepth(root.Left)
  rightDepth := maxDepth(root.Right)
  return max(leftDepth, rightDepth) + 1
}
func max(x, y int) int {
  if x > y {
    return x
  }
  return y
}
func buildTree(nums []int) *TreeNode {
  if len(nums) == 0 {
    return nil
  }
  root := &TreeNode{Val: nums[0]}
  Queue := []*TreeNode{root}
  idx := 1
  for idx < len(nums) {
    node := Queue[0]
    Queue = Queue[1:]
    if nums[idx] != null {
      node.Left = &TreeNode{Val: nums[idx]}
      Queue = append(Queue, node.Left)
    }
    idx++
    if idx < len(nums) && nums[idx] != null {
      node.Right = &TreeNode{Val: nums[idx]}
      Queue = append(Queue, node.Right)
    }
    idx++
  }
  return root
}
func main() {
  nums := []int{3, 9, 20, null, null, 15, 7}
  root := buildTree(nums)
  fmt.Println(maxDepth(root))
}



代码2: 迭代

1.package main
import (
  "fmt"
)
const null = -1 << 31
type TreeNode struct {
  Val   int
  Left  *TreeNode
  Right *TreeNode
}
func maxDepth(root *TreeNode) int {
  if root == nil {
    return 0
  }
  depth := 0
  queue := []*TreeNode{root}
  for len(queue) > 0 {
    size := len(queue)
    for i := 0; i < size; i++ {
      node := queue[0]
      queue = queue[1:]
      if node.Left != nil {
        queue = append(queue, node.Left)
      }
      if node.Right != nil {
        queue = append(queue, node.Right)
      }
    }
    depth++
  }
  return depth
}
func buildTree(nums []int) *TreeNode {
  if len(nums) == 0 {
    return nil
  }
  root := &TreeNode{Val: nums[0]}
  Queue := []*TreeNode{root}
  idx := 1
  for idx < len(nums) {
    node := Queue[0]
    Queue = Queue[1:]
    if nums[idx] != null {
      node.Left = &TreeNode{Val: nums[idx]}
      Queue = append(Queue, node.Left)
    }
    idx++
    if idx < len(nums) && nums[idx] != null {
      node.Right = &TreeNode{Val: nums[idx]}
      Queue = append(Queue, node.Right)
    }
    idx++
  }
  return root
}
func main() {
  nums := []int{3, 9, 20, null, null, 15, 7}
  root := buildTree(nums)
  fmt.Println(maxDepth(root))
}


输出:

3


105. 从前序与中序遍历序列构造二叉树 Construct-binary-tree-from-preorder-and-inorder-traversal


给定两个整数数组 preorder 和 inorder ,其中 preorder 是二叉树的先序遍历, inorder 是同一棵树的中序遍历,请构造二叉树并返回其根节点。


示例 1:

12e10269f1d1ee495f3aa4b8a8a95e11.jpeg

输入: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]

输出: [3,9,20,null,null,15,7]


示例 2:

输入: preorder = [-1], inorder = [-1]

输出: [-1]  


提示:

   1 <= preorder.length <= 3000

   inorder.length == preorder.length

   -3000 <= preorder[i], inorder[i] <= 3000

   preorder 和 inorder 均 无重复 元素

   inorder 均出现在 preorder

   preorder 保证 为二叉树的前序遍历序列

   inorder 保证 为二叉树的中序遍历序列


代码:

package main
import (
  "fmt"
)
const null = -1 << 31
type TreeNode struct {
  Val   int
  Left  *TreeNode
  Right *TreeNode
}
func buildTree(preorder []int, inorder []int) *TreeNode {
  index := make(map[int]int)
  for i, val := range inorder {
    index[val] = i
  }
  var build func(preStart, preEnd, inStart, inEnd int) *TreeNode
  build = func(preStart, preEnd, inStart, inEnd int) *TreeNode {
    if preStart > preEnd {
      return nil
    }
    rootVal := preorder[preStart]
    rootIndex := index[rootVal]
    leftSize := rootIndex - inStart
    rightSize := inEnd - rootIndex
    left := build(preStart+1, preStart+leftSize, inStart, rootIndex-1)
    right := build(preEnd-rightSize+1, preEnd, rootIndex+1, inEnd)
    return &TreeNode{Val: rootVal, Left: left, Right: right}
  }
  return build(0, len(preorder)-1, 0, len(inorder)-1)
}
func LevelOrder(root *TreeNode) [][]int {
  if root == nil {
    return [][]int{}
  }
  res := [][]int{}
  queue := []*TreeNode{root}
  level := 0
  for len(queue) > 0 {
    size := len(queue)
    levelRes := []int{}
    stack := []*TreeNode{}
    for i := 0; i < size; i++ {
      node := queue[0]
      queue = queue[1:]
      levelRes = append(levelRes, node.Val)
      if node.Right != nil {
        stack = append(stack, node.Right)
      }
      if node.Left != nil {
        stack = append(stack, node.Left)
      }
    }
    for i := len(stack) - 1; i >= 0; i-- {
      queue = append(queue, stack[i])
    }
    res = append(res, levelRes)
    level++
  }
  return res
}
func main() {
  preorder := []int{3, 9, 20, 15, 7}
  inorder := []int{9, 3, 15, 20, 7}
  root := buildTree(preorder, inorder)
  fmt.Println(LevelOrder(root))
}



输出:

[[3] [9 20] [15 7]]









目录
相关文章
|
Shell Linux 算法
Shell编程——弱数据类型的脚本语言快速入门指南
Shell编程——弱数据类型的脚本语言快速入门指南
195 0
Shell编程——弱数据类型的脚本语言快速入门指南
|
Go Linux Shell
Linux 终端命令之文件浏览(2) more
Linux 终端命令之文件浏览(2) more
173 0
Linux 终端命令之文件浏览(2) more
|
Shell 机器学习/深度学习 Linux
Linux 终端操作命令(2)内部命令
Linux 终端操作命令(2)内部命令
286 0
Linux 终端操作命令(2)内部命令
|
C++ 算法 存储
力扣 C++|一题多解之动态规划专题(2)
力扣 C++|一题多解之动态规划专题(2)
209 0
力扣 C++|一题多解之动态规划专题(2)
|
Python 索引
Python Numpy入门基础(一)创建数组
Python Numpy入门基础(一)创建数组
260 0
Python Numpy入门基础(一)创建数组
|
Java 容器 程序员
Java语言程序设计试卷6套
Java语言程序设计试卷6套
1184 0
Java语言程序设计试卷6套
|
2月前
|
存储 安全 Java
【Golang】(4)Go里面的指针如何?函数与方法怎么不一样?带你了解Go不同于其他高级语言的语法
结构体可以存储一组不同类型的数据,是一种符合类型。Go抛弃了类与继承,同时也抛弃了构造方法,刻意弱化了面向对象的功能,Go并非是一个传统OOP的语言,但是Go依旧有着OOP的影子,通过结构体和方法也可以模拟出一个类。
171 1
|
Go
Golang语言之管道channel快速入门篇
这篇文章是关于Go语言中管道(channel)的快速入门教程,涵盖了管道的基本使用、有缓冲和无缓冲管道的区别、管道的关闭、遍历、协程和管道的协同工作、单向通道的使用以及select多路复用的详细案例和解释。
633 4
Golang语言之管道channel快速入门篇
|
Go
Golang语言文件操作快速入门篇
这篇文章是关于Go语言文件操作快速入门的教程,涵盖了文件的读取、写入、复制操作以及使用标准库中的ioutil、bufio、os等包进行文件操作的详细案例。
241 4
Golang语言文件操作快速入门篇
|
Go
Golang语言之gRPC程序设计示例
这篇文章是关于Golang语言使用gRPC进行程序设计的详细教程,涵盖了RPC协议的介绍、gRPC环境的搭建、Protocol Buffers的使用、gRPC服务的编写和通信示例。
528 3
Golang语言之gRPC程序设计示例