五月集训(第20天)—二叉搜索树
二叉搜索树
1. 700. 二叉搜索树中的搜索
思路:
类似于二分查找
(1)val < root->val
,去左子树查找
(1)val > root->val
,去右子树查找
(1)val == root->val
,返回该结点,即为目标子树的根节点
class Solution {
public:
TreeNode* searchBST(TreeNode* root, int val) {
if (root == nullptr) return nullptr;
/* 只需要将找到的子树根节点返回即可 */
if (val < root->val) return searchBST(root->left, val);
else if (val > root->val) return searchBST(root->right, val);
return root;
}
};
2. 230. 二叉搜索树中第K小的元素
思路:
利用二叉搜索树的性质,root->left->val
< root->val
< root->right->val
,中序遍历得到的结果是升序排列的,则在中序遍历结果的基础上,记录一个k
的值,从最小值开始--k
,直到k == 0
时,找到了第k小的元素。
class Solution {
int ans = 0;
int kk; /* 用全局遍历,实时修改k的值 */
void dfs(TreeNode *root) {
if (root) {
dfs(root->left);
if (--kk == 0) ans = root->val;
dfs(root->right);
}
}
public:
int kthSmallest(TreeNode* root, int k) {
kk = k;
dfs(root);
return ans;
}
};
利用传引用实时修改k的值
class Solution {
int ans = 0;
void dfs(TreeNode *root, int &k) {
if (root) {
dfs(root->left, k);
if (--k == 0) ans = root->val;
dfs(root->right, k);
}
}
public:
int kthSmallest(TreeNode* root, int k) {
dfs(root, k);
return ans;
}
};
3. 108. 将有序数组转换为二叉搜索树
思路:
递归构造二叉搜索树,每次选中间值作为根结点,左边比它小的值构造一棵左子树,右边比它大的值构造一棵右子树,每棵子树的根节点是其中间值。
class Solution {
TreeNode* dfs(vector<int> &nums, int l, int r) {
if (l > r) return nullptr;
int mid = l + ((r - l) >> 1);
TreeNode *root = new TreeNode(nums[mid]);
root->left = dfs(nums, l, mid - 1); /* 构造左子树 */
root->right = dfs(nums, mid + 1, r); /* 构造右子树 */
return root; /* 返回子树的根节点 */
}
public:
TreeNode* sortedArrayToBST(vector<int>& nums) {
int l = 0, r = nums.size() - 1;
return dfs(nums, l, r);
}
};
4. 1382. 将二叉搜索树变平衡
思路:
平衡二叉树,即每个结点的左右子树的高度相差不超过1。
(1)中序遍历按升序将二叉搜索树中的每个结点的值放入数组ret
(2)按照第三题的思路,递归构造二叉搜索树,由于构造方法是找一个根节点,构造左右子树,所以构造出来的二叉搜索树一定是平衡的。
class Solution {
vector<int> ret;
void inorder(TreeNode *root) { /* 中序遍历,并保存遍历结果在 ret 中 */
if (root) {
inorder(root->left);
ret.push_back(root->val);
inorder(root->right);
}
}
TreeNode *dfs(int l, int r) { /* 递归构造平衡二叉搜索树 */
if (l > r) return nullptr;
int mid = l + ((r - l) >> 1);
TreeNode *root = new TreeNode(ret[mid]);
root->left = dfs(l, mid - 1);
root->right = dfs(mid + 1, r);
return root;
}
public:
TreeNode* balanceBST(TreeNode* root) {
ret.clear();
inorder(root); /* 利用中序遍历二叉搜索树,得到一个有序数组 */
int l = 0, r = ret.size() - 1;
return dfs(l, r);
}
};
东方欲晓,莫道君行早。