赞
踩
(1)递归:复用求最大深度
先递归遍历左子树,后右子树,所以当取到最大深度时,返回对应的节点值
func findBottomLeftValue(root *TreeNode) int { if root == nil { return 0 } height := 0 leftVal := 0 var getDepth func(root *TreeNode, depth int) getDepth = func(root *TreeNode, depth int) { if root == nil { return } depth++ getDepth(root.Left, depth) getDepth(root.Right, depth) if depth > height { height = depth leftVal = root.Val } } getDepth(root, 0) return leftVal }
(2)迭代:最后一层第一个值
func findBottomLeftValue(root *TreeNode) int { if root == nil { return 0 } queue := []*TreeNode{root} res := 0 for len(queue) > 0 { size := len(queue) for i:= 0; i < size; i++ { node := queue[0] if i == 0 { res = node.Val } queue = queue[1:] if node.Left != nil { queue = append(queue, node.Left) } if node.Right != nil { queue = append(queue,node.Right) } } } return res }
求二叉树所有路径的变体
(1)递归:递归判断当前节点到叶子节点之和是否为targetSum
func hasPathSum(root *TreeNode, targetSum int) bool {
if root == nil {
return false
}
if root.Left == nil && root.Right == nil {
return targetSum == root.Val
}
return hasPathSum(root.Left, targetSum - root.Val) || hasPathSum(root.Right, targetSum - root.Val)
}
(2)层序遍历:nodeQueue存储了根节点到包括当前节点的所有节点,sumQueue记录了根节点到该节点之和
func hasPathSum(root *TreeNode, targetSum int) bool { if root == nil { return false } nodeQueue := []*TreeNode{root} sumQueue := []int{root.Val} for i := 0; i < len(nodeQueue); i++ { node, sum := nodeQueue[i], sumQueue[i] if node.Left == nil && node.Right == nil { if sum == targetSum { return true } continue } if node.Left != nil { nodeQueue = append(nodeQueue, node.Left) sumQueue = append(sumQueue, sum + node.Left.Val) } if node.Right != nil { nodeQueue = append(nodeQueue, node.Right) sumQueue = append(sumQueue, sum + node.Right.Val) } } return false }
(1)递归:初始化记录路径;终止条件;递归左右子树
func pathSum(root *TreeNode, targetSum int) [][]int { res := make([][]int, 0) path := []int{} var help func(root *TreeNode, targetSum int) help = func(root *TreeNode, targetSum int) { if root == nil { return } path = append(path, root.Val) targetSum -= root.Val if root.Left == nil && root.Right == nil && targetSum == 0{ res = append(res, path) } help(root.Left, targetSum) help(root.Right, targetSum) } help(root, targetSum) return res }
(2)层序遍历:
遍历时对path变量使用append方法,会修改底层数组,进而会影响到pathQueue中的其它路径。需要为每个路径创建一个新的切片副本。
type group struct { Node *TreeNode Val []int } func pathSum(root *TreeNode, targetSum int) [][]int { var res [][]int if root == nil { return res } queue := []*group{{root, []int{root.Val}}} for len(queue) > 0 { node := queue[0].Node valArr := queue[0].Val queue = queue[1:] sum := 0 for _, val := range valArr { sum += val } if node.Left == nil && node.Right == nil && sum == targetSum { res = append(res, valArr) } valArrCp := make([]int, len(valArr)) copy(valArrCp, valArr) if node.Left != nil { valArr1 := valArrCp valArr1 = append(valArr1, node.Left.Val) queue = append(queue, &group{node.Left, valArr1}) } if node.Right != nil { valArr2 := valArrCp valArr2 = append(valArr2, node.Right.Val) queue = append(queue, &group{node.Right, valArr2}) } } return res }
(1)递归:找到后序数组中最后一个元素在中序数组中的位置。递归右子树和左子树
func buildTree(inorder []int, postorder []int) *TreeNode { var build func(inorderLeft, inorderRight int) *TreeNode build = func(inorderLeft, inorderRight int) *TreeNode { if inorderLeft > inorderRight { return nil } rootVal := postorder[len(postorder) - 1] postorder = postorder[:len(postorder) - 1] root := &TreeNode{Val:rootVal} i := 0 for i = 0; i < len(inorder); i++ { if inorder[i] == rootVal { break } } root.Right = build(i + 1, inorderRight) root.Left = build(inorderLeft, i - 1) return root } return build(0, len(inorder) - 1) }
(1)递归:找到前序数组中第一个元素在中序数组中的位置。递归左子树和右子树
func buildTree(preorder []int, inorder []int) *TreeNode { var build func(inorderLeft, inorderRight int) *TreeNode build = func(inorderLeft, inorderRight int) *TreeNode{ if inorderLeft > inorderRight { return nil } rootVal := preorder[0] root := &TreeNode{Val : rootVal} preorder = preorder[1:] i := 0 for i = 0; i < len(inorder); i++ { if inorder[i] == rootVal { break } } root.Left = build(inorderLeft, i - 1) root.Right = build(i + 1, inorderRight) return root } return build(0, len(inorder) - 1) }
513.找树左下角的值
112.路径总和 | 113.路径总和ii
106.从中序与后序遍历序列构造二叉树 | 105.从前序与中序遍历序列构造二叉树
递归求解通常需要公共变量提取,创建无返回值函数,或者返回值为bool
注意切片扩容,导致结果出错,切片深拷贝、浅拷贝
感谢代码随想录练习营大佬们的帮助和解答
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。