代码随想录day15|110平衡二叉树257二叉树所有路径404左叶子之和|01笔记

65 阅读3分钟
  • 110平衡二叉树

  • 代码随想录 (programmercarl.com)
  • 第一印象

  • 在递归后序遍历求子树高的过程中比较子树的大小,当子树差大于1时,将布尔值置为FALSE
  • 讲解观后感

  • 如果不选择设置全局变量布尔值,可以使用递归返回-1的方法
  • 解题代码

  •     /**
         * Definition for a binary tree node.
         * type TreeNode struct {
         *     Val int
         *     Left *TreeNode
         *     Right *TreeNode
         * }
         */
        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
        }
        // 返回以该节点为根节点的二叉树的高度,如果不是平衡二叉树了则返回-1
        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)
  • 第一印象

  • 判定一个叶子节点是不是左叶子,需要存储它的父节点。在遍历所有叶子结点的过程中,遇到左叶子节点便加到结果中即可。
  • 讲解观后感

  • 随想录中的办法是直接通过叶子节点的父节点来判断叶子节点,就不需要保留两个参数了。
  • 解题代码

  • 双参数前序递归
  •     /**
         * Definition for a binary tree node.
         * type TreeNode struct {
         *     Val int
         *     Left *TreeNode
         *     Right *TreeNode
         * }
         */
        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
        }