代码随想录算法训练营Day21 | 513.找树左下角的值、112.路径总和、113.路径总和 II、106.从中序与后序遍历序列构造二叉树

81 阅读2分钟

LeetCode题目

513.找树左下角的值

题目链接:Find Bottom Left Tree Value - LeetCode

代码如下:

迭代法

/**
 * Definition for a binary tree node.
 * type TreeNode struct {
 *     Val int
 *     Left *TreeNode
 *     Right *TreeNode
 * }
 */
func findBottomLeftValue(root *TreeNode) int {
	res := 0
	que := []*TreeNode{root}
	for len(que) > 0 {
		size := len(que)
		for i := 0; i < size; i++ {
			node := que[0]
			que = que[1:]
			if i == 0 {
				res = node.Val
			}
			if node.Left != nil {
				que = append(que, node.Left)
			}
			if node.Right != nil {
				que = append(que, node.Right)
			}
		}
	}
	return res
}

递归法

/**
 * Definition for a binary tree node.
 * type TreeNode struct {
 *     Val int
 *     Left *TreeNode
 *     Right *TreeNode
 * }
 */
func traversal(root *TreeNode, depth int, maxDepth, result *int) {
	if root.Left == nil && root.Right == nil {
		if depth > *maxDepth {
			*maxDepth = depth
			*result = root.Val
		}
		return
	}
	if root.Left != nil {
		traversal(root.Left, depth+1, maxDepth, result)
	}
	if root.Right != nil {
		traversal(root.Right, depth+1, maxDepth, result)
	}
	return
}

func findBottomLeftValue(root *TreeNode) int {
	maxDepth := -1
	result := 0
	traversal(root, 0, &maxDepth, &result)
	return result
}

112.路径总和

题目链接:Path Sum - LeetCode

代码如下:

/**
 * Definition for a binary tree node.
 * type TreeNode struct {
 *     Val int
 *     Left *TreeNode
 *     Right *TreeNode
 * }
 */
func hasPathSum(root *TreeNode, targetSum int) bool {
	if root == nil {
		return false
	}
	if root.Left == nil && root.Right == nil && targetSum == root.Val {
		return true
	}
	return hasPathSum(root.Left, targetSum-root.Val) || hasPathSum(root.Right, targetSum-root.Val)
}

113.路径总和 II

题目链接:Path Sum II - LeetCode

代码如下:

/**
 * Definition for a binary tree node.
 * type TreeNode struct {
 *     Val int
 *     Left *TreeNode
 *     Right *TreeNode
 * }
 */
func traversal(cur *TreeNode, count int, path *[]int, result *[][]int) {
	if cur.Left == nil && cur.Right == nil && count == 0 {
		// 不能直接将path放到result里面, 因为path是共享的, 每次遍历子树时都会被修改
		pathCopy := make([]int, len(*path))
		copy(pathCopy, *path)
		*result = append(*result, pathCopy) // 将副本放到结果集里
		return
	}
	if cur.Left == nil && cur.Right == nil && count != 0 {
		return
	}
	if cur.Left != nil {
		*path = append(*path, cur.Left.Val)
		count -= cur.Left.Val
		traversal(cur.Left, count, path, result)
		count += cur.Left.Val
		*path = (*path)[:len(*path)-1]
	}
	if cur.Right != nil {
		*path = append(*path, cur.Right.Val)
		count -= cur.Right.Val
		traversal(cur.Right, count, path, result)
		count += cur.Right.Val
		*path = (*path)[:len(*path)-1]
	}
	return
}

func pathSum(root *TreeNode, targetSum int) [][]int {
	result := [][]int{}
	path := []int{}
	if root == nil {
		return result
	}
	path = append(path, root.Val)
	traversal(root, targetSum-root.Val, &path, &result)
	return result
}

106.从中序与后序遍历序列构造二叉树

题目链接:Construct Binary Tree from Inorder and Postorder Traversal - LeetCode

代码如下:

/**
 * Definition for a binary tree node.
 * type TreeNode struct {
 *     Val int
 *     Left *TreeNode
 *     Right *TreeNode
 * }
 */
func traversal(inorder []int, postorder []int) *TreeNode {
	if len(postorder) == 0 {
		return nil
	}
	rootVal := postorder[len(postorder)-1]
	root := &TreeNode{
		Val:   rootVal,
		Left:  nil,
		Right: nil,
	}
	if len(postorder) == 1 {
		return root
	}
	delimiterIndex := 0
	for delimiterIndex = 0; delimiterIndex < len(inorder); delimiterIndex++ {
		if inorder[delimiterIndex] == rootVal {
			break
		}
	}
	leftInorder := inorder[:delimiterIndex]
	rightInorder := inorder[delimiterIndex+1:]
	postorder = postorder[:len(postorder)-1]
	leftPostorder := postorder[:len(leftInorder)]
	rightPostorder := postorder[len(leftInorder):]
	root.Left = traversal(leftInorder, leftPostorder)
	root.Right = traversal(rightInorder, rightPostorder)
	return root
}

func buildTree(inorder []int, postorder []int) *TreeNode {
	if len(inorder) == 0 || len(postorder) == 0 {
		return nil
	}
	return traversal(inorder, postorder)
}

总结

  1. 如果需要搜索整棵二叉树且不用处理递归返回值,递归函数就不要返回值(113.路径总和II)
  2. 如果需要搜索整棵二叉树且需要处理递归返回值,递归函数就需要返回值(236.二叉树的最近公共祖先)
  3. 如果要搜索其中一条符合条件的路径,那么递归一定需要返回值,因为遇到符合条件的路径了就要及时返回(112.路径总和)