代码随想录day14 || 226 翻转二叉树,101 对称二叉树, 104 二叉树的最大深度, 111 二叉树的最小深度
226 翻转二叉树
copy
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
func invertTree(root *TreeNode) *TreeNode {
// 思考,广度优先遍历,对于每一层,翻转其左右子节点
if root == nil {
return nil
}
queue := list.New()
queue.PushBack(root)
size := 1 // 存储每一层的节点个数
for queue.Len() > 0{
var count int
for i:=0; i<size; i++{ // 弹出该层所有的节点
node := queue.Remove(queue.Front()).(*TreeNode)
// 将该节点的左右子节点翻转
if node.Left != nil || node.Right != nil {
node.Left, node.Right = node.Right, node.Left
}
// 将翻转后的子节点入队列
if node.Left != nil {
queue.PushBack(node.Left)
count++
}
if node.Right != nil {
queue.PushBack(node.Right)
count++
}
}
size = count
}
return root
}
// list双向链表实现的队列,插入移除操作复杂度都是1
// 所以时间 遍历翻转每一个节点 n 空间 队列 n
copy
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
func invertTree(root *TreeNode) *TreeNode { // 递归参数返回值
// 递归前序遍历
if root == nil { // 递归终止条件
return nil
}
// 交换左右子节点
if root.Left != nil || root.Right != nil { // 单次递归逻辑
root.Left, root.Right = root.Right, root.Left
}
invertTree(root.Left)
invertTree(root.Right)
return root
}
// 时间复杂度n 空间 如果平衡二叉树logn 如果链表 n
// 递归前序后序遍历都可以直观理解,但是中序时候,需要特殊处理递归逻辑,因为先一步递归左子树之后,处理完交换逻辑左子树变成了右子树,此时往下执行交换右子树就是错误的,所以之后的逻辑应该改成仍然交互左子树
101 判断二叉树对称
copy
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
func isSymmetric(root *TreeNode) bool {
// 递归
if root == nil {
return true
}
return symmetric(root.Left, root.Right)
}
func symmetric(left, right *TreeNode) bool { // 递归参数返回值
// 递归终止条件
if left == nil && right != nil ||
left != nil && right == nil ||
left != nil && right != nil && left.Val != right.Val {
// 左空右非空 || 左非空右边空 || 左右数值不相等
return false
}
if left == nil && right == nil {
return true
}
// 最后一种情况,左右非空并且值相等
// 递归逻辑
inner := symmetric(left.Left, right.Right)
outer := symmetric(left.Right, right.Left)
return inner && outer
}
时间,每个节点遍历一次 n 空间logn
104 最大深度
copy
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
func maxDepth(root *TreeNode) int {
// 考虑层序遍历
if root == nil {
return 0
}
queue := list.New()
queue.PushBack(root)
dep := 1
size := 1
for queue.Len() >0{
var count int
for i:=0; i<size; i++ {
node := queue.Remove(queue.Front()).(*TreeNode)
if node.Left != nil {
queue.PushBack(node.Left)
count++
}
if node.Right != nil {
queue.PushBack(node.Right)
count++
}
}
if count == 0{
return dep
}
size = count
dep++
}
return dep
}
// 层序遍历每个节点遍历一次,时间n 空间 队列长度最长为n/2 = n
copy
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
func maxDepth(root *TreeNode) int {
// 递归方法,深度优先遍历,因为需要不断传递子节点高度给父节点,所以考虑后续遍历,同时根节点高度就是树的深度
if root == nil {
return 0
}
left := maxDepth(root.Left)
right := maxDepth(root.Right)
var res int = right
if left > right {
res = left
}
return res+1
}
111 最小深度
copy
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
func minDepth(root *TreeNode) int {
// 思考层序遍历,终止条件是左右子树都是空
if root == nil {
return 0
}
queue := list.New()
queue.PushBack(root)
dep := 1
size := 1
for queue.Len() >0 {
var count int
for i := 0; i < size; i++ {
node := queue.Remove(queue.Front()).(*TreeNode)
if node.Left == nil && node.Right == nil {
return dep
}
if node.Left != nil {
queue.PushBack(node.Left)
count++
}
if node.Right != nil {
queue.PushBack(node.Right)
count++
}
}
size = count
dep++
}
return dep
}
// 层序遍历每个节点遍历一次,时间n 空间 队列长度最长为n/2 = n
copy
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
func minDepth(root *TreeNode) int {
// 递归方法,深度优先遍历,最小深度,终止条件是遇到无叶子的子节点,从上往下传递,中左右前序遍历
if root == nil {
return 0
}
// 如果左子树为空,递归右子树
if root.Left == nil {
return minDepth(root.Right) + 1
}
// 如果右子树为空,递归左子树
if root.Right == nil {
return minDepth(root.Left) + 1
}
// 左右子树都不为空,返回左右子树的最小深度
leftDepth := minDepth(root.Left)
rightDepth := minDepth(root.Right)
return int(math.Min(float64(leftDepth), float64(rightDepth))) + 1
}
本文作者:周公瑾55
本文链接:https://www.cnblogs.com/zhougongjin55/p/18332121
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
本文作者:周公瑾55
本文链接:https://www.cnblogs.com/zhougongjin55/p/18332121
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步