1 二叉搜索树的定义
二叉搜索树(Binary Search Tree)简称BST,对于BST中的每一个节点node:
-
如果左子树的值都比node小。
-
右子树的值都比node大。
那么这颗树为二叉搜索树。
2 二叉搜索树的性质
中序遍历递增,很多二叉搜索树的题目都是基于这一性质来展开的,很重要。
void traverse(TreeNode root) {
if (root == null) return;
traverse(root.left);
// 中序遍历代码位置
print(root.val);
traverse(root.right);
}
当然,既然可以递增遍历,那么可不可以递减遍历呢? 当然可以,只需要将left和right顺序置换一下就可以了,下面有道题目就是需要递减遍历。
void traverse(TreeNode root) {
if (root == null) return;
traverse(root.right);
// 中序遍历代码位置
print(root.val);
traverse(root.left);
}
3 题目
3.1 230. 二叉搜索树中第K小的元素
3.1.1 题目
给定一个二叉搜索树,编写一个函数 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
3.1.2 思路
由于是二叉搜索树相关的题目,首先就应该想起BST的性质:中序遍历递增,既然如此,中序遍历中第k次被访问的节点就为第k小的节点。
3.1.3 代码
class Solution {
int res = 0;
int rank = 0;
public int kthSmallest(TreeNode root, int k) {
traverse(root, k);
return res;
}
void traverse(TreeNode root, int k) {
if (root == null) {
return;
}
traverse(root.left, k);
/* ---- 中序遍历位置 ---- */
rank++;
if (rank == k) {
res = root.val;
return;
}
/*************************/
traverse(root.right, k);
}
}
3.2 538. 把二叉搜索树转换为累加树
3.2.1 题目
给出二叉 搜索 树的根节点,该树的节点值各不相同,请你将其转换为累加树(Greater Sum Tree),使每个节点 node 的新值等于原树中大于或等于 node.val 的值之和。
提醒一下,二叉搜索树满足下列约束条件:
- 节点的左子树仅包含键 小于 节点键的节点。
- 节点的右子树仅包含键 大于 节点键的节点。
- 左右子树也必须是二叉搜索树。
**注意:**本题和 1038: https://leetcode-cn.com/problems/binary-search-tree-to-greater-sum-tree/ 相同
示例 1:

输入:[4,1,6,0,2,5,7,null,null,null,3,null,null,null,8]
输出:[30,36,21,36,35,26,15,null,null,null,33,null,null,null,8]
示例 2:
输入:root = [0,null,1]
输出:[1,null,1]
示例 3:
输入:root = [1,0,2]
输出:[3,3,2]
示例 4:
输入:root = [3,2,4,1]
输出:[7,9,4,10]
3.2.2 思路
题目中所指的累加树是指当前节点的值为树中大于或等于该节点的值,而原树却是一个二叉搜索树,那么可以从树中从大至小依次遍历,依次累加替换当前节点的值。
根据二叉搜索树的性质,可以想到使用中序遍历的递减形式。
首先,只有清楚了函数的功能以及返回值的意义,才能够快速帮助我们理解递归函数本身,我认为这是非常重要的一步。
-
函数的功能,传入当前节点
root与遍历的累加值sum,替换当前节点的值。 -
函数的返回值,以当前节点为根的树的累加值。
这样,如何用代码写出该题就清晰起来了。
3.2.3 代码
class Solution {
public TreeNode convertBST(TreeNode root) {
traverse(root, 0);
return root;
}
int traverse(TreeNode root, int sum) {
if (root == null) {
return sum;
}
int rightSum = traverse(root.right, sum);
/* ---- 中序遍历位置 ----*/
root.val += rightSum;
/************************/
return traverse(root.left, root.val);
}
}
本文介绍二叉搜索树的基础概念与特性,并通过两道典型题目:查找第k小的元素及转换为累加树,展示其在算法题中的应用技巧。
633

被折叠的 条评论
为什么被折叠?



