题目描述
给你二叉树的根节点 root ,返回它节点值的 前序 遍历
方法一:递归
解题思路
- 前序遍历先保存根节点
- 然后遍历左子树
- 最后遍历右子树
代码实现
func preorderTraversal(root *TreeNode) []int {
var res []int
if root == nil {
return res
}
res = append(res, root.Val)
res = append(res, preorderTraversal(root.Left)...)
res = append(res, preorderTraversal(root.Right)...)
return res
}
方法二:迭代
解题思路
- 利用队列先进先出来保存走过的节点
- 保存根节点
- 一路向左,到头了从队列取出一个节点
代码实现
func preorderTraversal(root *TreeNode) []int {
res := make([]int, 0)
if root == nil {
return res
}
queue := make([]*TreeNode, 0)
for root != nil || len(queue) > 0 {
for root != nil {
// 前序遍历,先保存根节点
res = append(res, root.Val)
// 入队列
queue = append(queue, root)
root = root.Left
}
// 出队列
node := queue[len(queue)-1]
queue = queue[:len(queue)-1]
// 回溯
root = node.Right
}
return res
}
方法三:dfs
解题思路
- 深度优先搜索,思路类似于前序递归
- 将保存最终结果的切片地址当参数传入进行递归
代码实现
func preorderTraversal(root *TreeNode) []int {
var res []int
if root == nil {
return res
}
dfs(root, &res)
return res
}
func dfs(root *TreeNode, res *[]int) {
if root == nil {
return
}
*res = append(*res, root.Val)
dfs(root.Left, res)
dfs(root.Right, res)
}
方法四:dfs分治法
解题思路
- 与方法三的区别是方法三将最终结果的地址传参
- 分治法是将最终结果返回再合并
- 个人感觉就是两种传参形式不同
代码实现
func preorderTraversal(root *TreeNode) []int {
if root == nil {
return nil
}
return dfs(root)
}
func dfs(root *TreeNode) []int {
var res []int
if root == nil {
return res
}
// 分治
leftRes := dfs(root.Left)
rightRes := dfs(root.Right)
// 合并
res = append(res, root.Val)
res = append(res, leftRes...)
res = append(res, rightRes...)
return res
}
}