637.二叉树的层平均值
题目
给定一个非空二叉树, 返回一个由每层节点平均值组成的数组.
示例 1:
输入:
3
/ \
9 20
/ \
15 7
输出: [3, 14.5, 11]
解释:
第0层的平均值是 3, 第1层是 14.5, 第2层是 11. 因此返回 [3, 14.5, 11].
注意:
节点值的范围在32位有符号整数范围内。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/average-of-levels-in-binary-tree
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 题解
层次遍历,得到每一层的节点总数和节点和总值计算平均值, 使用广度优先搜索。
代码
func averageOfLevels(root *TreeNode) []float64 {
res := []float64{}
if root == nil {
return res
}
cnt, sum := 0, 0 // 统计节点数和节点值和
q := []*TreeNode{root} // 切片当队列使用
for len(q) > 0 {
cnt = len(q)
sum = 0
for i := 0; i < cnt; i++ { // 遍历当前层的节点,并将下层节点添加到队列
tmp := q[0]
q = q[1:]
if tmp.Left != nil { // 左子树入队
q = append(q, tmp.Left)
}
if tmp.Right != nil { // 右子树入队
q = append(q, tmp.Right)
}
sum += tmp.Val
}
// 计算该层的平均值
res = append(res, float64(sum) / float64(cnt))
}
return res
} 513. 找树左下角的值
题目
给定一个二叉树,在树的最后一行找到最左边的值。
示例 1:
输入:
2
/ \
1 3
输出:
1
示例 2:
输入:
1
/ \
2 3
/ / \
4 5 6
/
7
输出:
7
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/find-bottom-left-tree-value
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 题解
使用深度优先搜索记录层数,每次遇到的第一个元素即是最左子树, 也可以通过广度优先搜索求解。
代码
var maxd, val int
func findBottomLeftValue(root *TreeNode) int {
maxd, val = 0, 0
dfs(root, 1)
return val
}
// 深度优先搜索
func dfs(root *TreeNode, d int) {
if root == nil {
return
}
if d > maxd {
maxd = d
val = root.Val
}
if root.Left != nil {
dfs(root.Left, d+1)
}
if root.Right != nil {
dfs(root.Right, d + 1)
}
} 144. 二叉树的前序遍历(非递归)
题目
给定一个二叉树,返回它的 前序 遍历。
示例:
输入: [1,null,2,3]
1
\
2
/
3
输出: [1,2,3]
进阶: 递归算法很简单,你可以通过迭代算法完成吗?
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/binary-tree-preorder-traversal
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 题解
前序遍历: 根->左->右。 使用栈模拟递归即可, 栈用go的切片进行模拟。
代码
func preorderTraversal(root *TreeNode) []int {
res := []int{}
stack :=[]*TreeNode{root} // 使用切片模拟栈
for len(stack) > 0 {
// 切片模拟出栈
s := stack[len(stack) - 1]
stack = stack[:len(stack) - 1]
if s == nil {
continue
}
res = append(res, s.Val)
// 右子树先入栈,保证先出栈的为左子树
stack = append(stack, s.Right)
stack = append(stack, s.Left)
}
return res
} 145.非递归实现二叉树的后序遍历
题目
给定一个二叉树,返回它的 后序 遍历。
示例:
输入: [1,null,2,3]
1
\
2
/
3
输出: [3,2,1]
进阶: 递归算法很简单,你可以通过迭代算法完成吗?
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/binary-tree-postorder-traversal
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 题解
后序遍历左->右->根, 等价于根->右->左遍历后结果的翻转。修改非递归实现的先序遍历代码的左右子树的入栈顺序,再将结果进行一次翻转即可得到结果。
代码
// 非递归实现二叉树的后序遍历
func postorderTraversal(root *TreeNode) []int {
// 非递归实现二叉树的后序遍历
res := []int{}
stack :=[]*TreeNode{root} // 使用切片模拟栈
for len(stack) > 0 {
// 切片模拟出栈
s := stack[len(stack) - 1]
stack = stack[:len(stack) - 1]
if s == nil {
continue
}
res = append(res, s.Val)
stack = append(stack, s.Left)// 左子树先入栈, 保证右子树先出站
stack = append(stack, s.Right)
}
res = reverses(res)
return res
}
// 切片翻转
func reverses(s []int) []int {
for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 {
s[i], s[j] = s[j], s[i]
}
return s
} 94.非递归实现二叉树的中序遍历
题目
给定一个二叉树,返回它的中序 遍历。
示例:
输入: [1,null,2,3]
1
\
2
/
3
输出: [1,3,2]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/binary-tree-inorder-traversal
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 题解
二叉树的中序遍历, 左根右。
先将左子树全部进栈,然后取栈顶元素进行输出,接着右子树开始进栈。
代码
// 非递归实现二叉树的中序遍历
func inorderTraversal(root *TreeNode) []int {
res := []int{}
if root == nil {
return res
}
stack := []*TreeNode{}
cur := root
for cur != nil || len(stack) > 0 {
for cur != nil { // 先将左子树进栈
stack = append(stack, cur)
cur = cur.Left
}
// 取栈顶元素,即为根
node := stack[len(stack)-1]
stack = stack[:len(stack)-1]
res = append(res, node.Val)
// 遍历右子树
cur = node.Right
}
return res
} 669.修剪二叉搜索树
题目
给定一个二叉搜索树,同时给定最小边界L 和最大边界 R。通过修剪二叉搜索树,使得所有节点的值在[L, R]中 (R>=L) 。你可能需要改变树的根节点,所以结果应当返回修剪好的二叉搜索树的新的根节点。
示例 1:
输入:
1
/ \
0 2
L = 1
R = 2
输出:
1
\
2
示例 2:
输入:
3
/ \
0 4
\
2
/
1
L = 1
R = 3
输出:
3
/
2
/
1
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/trim-a-binary-search-tree
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 题解
二叉搜索树是具有有以下性质的二叉树:
- 若左子树不为空,则左子树上所有节点的值均小于或等于它的根节点的值。
- 若右子树不为空,则右子树上所有节点的值均大于或等于它的根节点的值。
- 左、右子树也分别为二叉搜索树。
修剪操作, 如当前节点的指针指向左子树,需要将左子树剪掉,将当前节点的指针指向左子树的子节点上,以此类推。
代码
func trimBST(root *TreeNode, L int, R int) *TreeNode {
if root == nil {
return nil
}
if root.Val > R {
return trimBST(root.Left, L, R)
}
if root.Val < L {
return trimBST(root.Right, L, R)
}
root.Left = trimBST(root.Left, L, R)
root.Right = trimBST(root.Right, L, R)
return root
} 230. 二叉搜索中第k小的元素
题目
给定一个二叉搜索树,编写一个函数 kthSmallest 来查找其中第 k 个最小的元素。
说明:
你可以假设 k 总是有效的,1 ≤ k ≤ 二叉搜索树元素个数。
示例 1:
输入: root = [3,1,4,null,2], k = 1
3
/ \
1 4
\
2
输出: 1
示例 2:
输入: root = [5,3,6,2,4,null,null,1], k = 3
5
/ \
3 6
/ \
2 4
/
1
输出: 3
进阶:
如果二叉搜索树经常被修改(插入/删除操作)并且你需要频繁地查找第 k 小的值,你将如何优化 kthSmallest 函数?
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/kth-smallest-element-in-a-bst
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 题解
二叉搜索树使用中序遍历, 第k个就是结果, 使用递归解法。
代码
// 求二叉搜索树第k小的元素
func kthSmallest(root *TreeNode, k int) int {
leftCnt := count(root.Left)
if leftCnt == k - 1 {
return root.Val
}
if leftCnt > k - 1 {
return kthSmallest(root.Left, k)
}
return kthSmallest(root.Right, k - leftCnt - 1)
}
func count(node *TreeNode) int {
if node == nil {
return 0
}
return 1 + count(node.Left) + count(node.Right)
} 235.二叉搜索树的最近公共祖先
题目
给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。 百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。” 例如,给定如下二叉搜索树: root = [6,2,8,0,4,7,9,null,null,3,5] 示例 1: 输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8 输出: 6 解释: 节点 2 和节点 8 的最近公共祖先是 6。 示例 2: 输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 4 输出: 2 解释: 节点 2 和节点 4 的最近公共祖先是 2, 因为根据定义最近公共祖先节点可以为节点本身。 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-search-tree 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
题解
- 两个节点分别在左右子树,公共祖先是根节点;
- 两个节点都在左子树;
- 两个节点都在右子树;
代码
//求二叉搜索树的最近公共祖先
func lowestCommonAncestor(root, p, q *TreeNode) *TreeNode {
if root.Val > p.Val && root.Val > q.Val { // 节点都在左子树
return lowestCommonAncestor(root.Left, p, q)
}
if root.Val < p.Val && root.Val < q.Val { // 节点都在右子树
return lowestCommonAncestor(root.Right, p, q)
}
return root
} 236.二叉树的最近公共祖先
题目
给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。 百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。” 例如,给定如下二叉树: root = [3,5,1,6,2,0,8,null,null,7,4] 示例 1: 输入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1 输出: 3 解释: 节点 5 和节点 1 的最近公共祖先是节点 3。 示例 2: 输入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4 输出: 5 解释: 节点 5 和节点 4 的最近公共祖先是节点 5。因为根据定义最近公共祖先节点可以为节点本身。 说明: 所有节点的值都是唯一的。 p、q 为不同节点且均存在于给定的二叉树中。 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-tree 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
题解
- 如果该节点就是子节点的其中之一,且能够通过该节点找到另一个子节点,那么这个节点就是最近公共祖先;
- 如果通过该节点不能找到两个子节点的,不是公共祖先,需要往上找;
- 如果通过该节点能找到两个子节点的,且分别位于其左子树或右子树上的,其就是最近公共祖先。
- 如果通过该节点能找到两个子节点的,且全部位于左子树或者右子树上的,是公共祖先,但不是最近的公共祖先,需要继续往下找。
代码
// 求二叉树的最近公共祖先
func lowestCommonAncestor(root, p, q *TreeNode) *TreeNode {
if root == nil || root == p || root == q {
return root
}
left := lowestCommonAncestor(root.Left, p, q)
right := lowestCommonAncestor(root.Right, p, q)
if left != nil && right != nil {
return root
}
if left != nil {
return left
}
return right
} 653.两数之和IV-输入BST
题目
给定一个二叉搜索树和一个目标结果,如果 BST 中存在两个元素且它们的和等于给定的目标结果,则返回 true。
案例 1:
输入:
5
/ \
3 6
/ \ \
2 4 7
Target = 9
输出: True
案例 2:
输入:
5
/ \
3 6
/ \ \
2 4 7
Target = 28
输出: False
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/two-sum-iv-input-is-a-bst
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 题解
- 二叉查找树进行中序遍历,得到的序列是有序的,
- 再利用双指针进行求解即可。
代码
// 在二叉树中查找两个节点使之和等于k
func findTarget(root *TreeNode, k int) bool {
nums := []int{}
toArray(root, &nums)
i, j := 0, len(nums) - 1
for i < j {
sum := nums[i] + nums[j]
if sum == k {
return true
}
if sum < k {
i++
}else {
j--
}
}
return false
}
// 二叉查找树中序遍历后得到一个有序数组
func toArray(root *TreeNode, arr *[]int){
if root == nil {
return
}
toArray(root.Left, arr)
*arr = append(*arr, root.Val)
toArray(root.Right, arr)
}
京公网安备 11010502036488号