题目:102. 二叉树的层序遍历
思路:
先把根放进去,然后每次都是左右就可以了。
记录一个深度,当len(res) == deepth
的时候就说明这个深度还没有实例化,先搞一个再去收集。
代码:
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
var res [][]int
func levelOrder(root *TreeNode) [][]int {
res = [][]int{}
level(root,0) // 根
return res
}
func level(t *TreeNode,deepth int) {
if t == nil { // 如果没有就返回
return
}
if len(res) == deepth { // 实例化这一层
res = append(res, []int{})
}
res[deepth] = append(res[deepth], t.Val) // 在这一层添加数据
level(t.Left, deepth+1) // 遍历左节点
level(t.Right, deepth+1) // 遍历右节点
}
参考:
题目:226. 翻转二叉树
思路:
二叉树的题递归分三步:
- 确定递归函数的参数和返回值
- 确定终止条件
- 确定单层递归的逻辑(前序、中序、后序、层序)
翻转二叉树,参数必然是树的指针,返回的结果是翻转后的二叉树同样也是一个树的指针。
当没有节点可以翻转了就结束。
这道题可以先把根翻转了,再去翻转左右节点可以;也可以先翻转左右节点再去翻转根,因此选择前序或者后序遍历。翻转就是把左右节点交换。可以尝试结合画图来理解。
代码:
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func invertTree(root *TreeNode) *TreeNode {
if root == nil { // 空就不翻转
return nil
}
root.Left, root.Right = root.Right, root.Left
invertTree(root.Left)
invertTree(root.Right)
return root
}
参考:
题目:101. 对称二叉树
思路:
二叉树的题递归分三步:
- 确定递归函数的参数和返回值
- 确定终止条件
- 确定单层递归的逻辑(前序、中序、后序、层序)
这题是需要两个子树同时进行的,想要判断对称:
- 左子树的左侧 = 右子树的右侧 ,即外侧相同
- 左子树的右侧 = 右子树的左侧 ,即内侧相同
那么参数就是一个左子树一个右子树,返回结果为true 或者 false。
终止条件是出现false:
- 左子树nil,右子树不为nil
- 左子树不为nil,右子树nil
- 左子树不为nil,右子树不为nil,但是左子树不等于右子树
以及true的条件:左子树 = 右子树 = nil (左子树 = 右子树 ≠ nil的情况是继续向下递归因此不是终止条件)
本题只能是后序遍历,因为我们要通过递归函数的返回值来判断两个子树的内侧节点和外侧节点是否相等
代码:
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func isSymmetric(root *TreeNode) bool {
if root == nil {
return true
}
return compare(root.Left, root.Right)
}
func compare(left, right *TreeNode) bool {
if left != nil && right == nil {
return false
}else if left == nil && right != nil {
return false
}else if left == nil && right == nil {
return true
}else if left.Val != right.Val {
return false
}
outside := compare(left.Left, right.Right) // 外侧是不是相同
inside := compare(left.Right, right.Left) // 内侧是不是相同
root := outside && inside // 根节点根据内外侧是否相同来决定是true还是false
return root
}