-
110平衡二叉树
- 代码随想录 (programmercarl.com)
-
第一印象
- 在递归后序遍历求子树高的过程中比较子树的大小,当子树差大于1时,将布尔值置为FALSE
-
讲解观后感
- 如果不选择设置全局变量布尔值,可以使用递归返回-1的方法
-
解题代码
-
var ans bool
func isBalanced(root *TreeNode) bool {
ans = true
getHeight(root)
return ans
}
func getHeight(node *TreeNode) int {
if node==nil {
return 0
}
lh := getHeight(node.Left)
rh := getHeight(node.Right)
if lh-rh>1 || rh-lh>1 {
ans = false
}
return 1+maxH(lh, rh)
}
func maxH(x int, y int) int {
if x > y {
return x
} else {
return y
}
}
- 返回-1
-
func isBalanced(root *TreeNode) bool {
h := getHeight(root)
if h == -1 {
return false
}
return true
}
func getHeight(root *TreeNode) int {
if root == nil {
return 0
}
l, r := getHeight(root.Left), getHeight(root.Right)
if l == -1 || r == -1 {
return -1
}
if l - r > 1 || r - l > 1 {
return -1
}
return max(l, r) + 1
}
func max(a, b int) int {
if a > b {
return a
}
return b
}
-
257二叉树所有路径
- 代码随想录 (programmercarl.com)
-
第一印象
- 路径就是从根节点到叶子节点的过程,也就是从根节点找叶子节点。每次找到叶子节点后记录当前走过的路径,然后再进行回溯,寻找下一个叶子节点。
-
讲解观后感
- 要注意回溯存在于每次寻找子节点的过程中。在golang中可以利用string类型传参来达成回溯的目的
-
解题代码
- 前序遍历:
-
func binaryTreePaths(root *TreeNode) []string {
res := make([]string, 0)
var travel func(node *TreeNode, s string)
travel = func(node *TreeNode, s string) {
if node.Left == nil && node.Right == nil {
v := s + strconv.Itoa(node.Val)
res = append(res, v)
return
}
s = s + strconv.Itoa(node.Val) + "->"
if node.Left != nil {
travel(node.Left, s)
}
if node.Right != nil {
travel(node.Right, s)
}
}
travel(root, "")
return res
}
- 迭代:
- 使用paths切片保存每个节点的path,达成回溯的目的
-
func binaryTreePaths(root *TreeNode) []string {
stack := []*TreeNode{}
paths := make([]string, 0)
res := make([]string, 0)
if root != nil {
stack = append(stack, root)
paths = append(paths, "")
}
for len(stack) > 0 {
l := len(stack)
node := stack[l-1]
path := paths[l-1]
stack = stack[:l-1]
paths = paths[:l-1]
if node.Left == nil && node.Right == nil {
res = append(res, path+strconv.Itoa(node.Val))
continue
}
if node.Right != nil {
stack = append(stack, node.Right)
paths = append(paths, path+strconv.Itoa(node.Val)+"->")
}
if node.Left != nil {
stack = append(stack, node.Left)
paths = append(paths, path+strconv.Itoa(node.Val)+"->")
}
}
return res
}
-
404左叶子之和
- 代码随想录 (programmercarl.com)
-
第一印象
- 判定一个叶子节点是不是左叶子,需要存储它的父节点。在遍历所有叶子结点的过程中,遇到左叶子节点便加到结果中即可。
-
讲解观后感
- 随想录中的办法是直接通过叶子节点的父节点来判断叶子节点,就不需要保留两个参数了。
-
解题代码
- 双参数前序递归
-
var res int
func sumOfLeftLeaves(root *TreeNode) int {
res = 0
serchLeave(root, root)
return res
}
func serchLeave(node *TreeNode, pre *TreeNode) {
if node.Left==nil && node.Right==nil {
if pre.Right==node {
return
}
if pre.Left==node {
res+=node.Val
return
}
}
if node.Left!=nil {
serchLeave(node.Left, node)
}
if node.Right!=nil {
serchLeave(node.Right, node)
}
return
}
- 单参数中序递归
-
func sumOfLeftLeaves(root *TreeNode) int {
if root == nil {
return 0
}
leftValue := sumOfLeftLeaves(root.Left)
if root.Left != nil && root.Left.Left == nil && root.Left.Right == nil {
leftValue = root.Left.Val
}
rightValue := sumOfLeftLeaves(root.Right)
return leftValue + rightValue
}
- 单参数前序迭代
-
func sumOfLeftLeaves(root *TreeNode) int {
if root == nil {
return 0
}
leftValue := sumOfLeftLeaves(root.Left)
if root.Left != nil && root.Left.Left == nil && root.Left.Right == nil {
leftValue = root.Left.Val
}
rightValue := sumOfLeftLeaves(root.Right)
return leftValue + rightValue
}
迭代法(前序遍历)
func sumOfLeftLeaves(root *TreeNode) int {
st := make([]*TreeNode, 0)
if root == nil {
return 0
}
st = append(st, root)
result := 0
for len(st) != 0 {
node := st[len(st)-1]
st = st[:len(st)-1]
if node.Left != nil && node.Left.Left == nil && node.Left.Right == nil {
result += node.Left.Val
}
if node.Right != nil {
st = append(st, node.Right)
}
if node.Left != nil {
st = append(st, node.Left)
}
}
return result
}