530. 二叉搜索树的最小绝对差
给你一个二叉搜索树的根节点 root ,返回 树中任意两不同节点值之间的最小差值 。
差值是一个正数,其数值等于两值之差的绝对值。
示例 1:
输入:root = [4,2,6,1,3]
输出:1
示例 2:
输入:root = [1,0,48,null,null,12,49]
输出:1
提示:
树中节点的数目范围是 [2, 10^4]
0 <= Node.val <= 10^5
思路:用左子树和右子树的范围计算差值,很罗嗦,耗时长
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
int getMinimumDifference(TreeNode* root) {
auto f = found(root);
return f[0];
}
vector<int> found(TreeNode* root){
int min_range, max_range;
int sub = 100002;
if(root->left == nullptr){
min_range = root->val;
}else{
auto left_found = found(root->left);
min_range = left_found[1];
sub = min(sub, left_found[0]);
sub = min(sub, (root->val - left_found[2]));
}
if(root->right == nullptr){
max_range = root->val;
}else{
auto right_found = found(root->right);
max_range = right_found[2];
sub = min(sub, right_found[0]);
sub = min(sub, (right_found[1] - root->val));
}
return {sub, min_range, max_range};
}
};
思路:用中序遍历,记住中序遍历中前一个节点的数值
class Solution {
private:
int pre = -1;
int min_sub = 100002;
public:
int getMinimumDifference(TreeNode* root) {
if(root == nullptr) return min_sub;
getMinimumDifference(root->left);
if(pre == -1) pre = root->val;
else{
min_sub = min(min_sub, root->val - pre);
pre = root->val;
}
getMinimumDifference(root->right);
return min_sub;
}
};
230. 二叉搜索树中第K小的元素
给定一个二叉搜索树的根节点 root
,和一个整数 k
,请你设计一个算法查找其中第 k
个最小元素(从 1 开始计数)。
示例 1:
输入:root = [3,1,4,null,2], k = 1
输出:1
示例 2:
输入:root = [5,3,6,2,4,null,null,1], k = 3
输出:3
提示:
树中的节点数为 n 。
1 <= k <= n <= 10^4
0 <= Node.val <= 10^4
思路:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
private:
int count = 0;
public:
int kthSmallest(TreeNode* root, int k) {
if(root == nullptr) return -1;
if(count > k) return -1;
int left = kthSmallest(root->left, k);
count ++;
if(count == k) return root->val;
int right = kthSmallest(root->right, k);
return max(left, right);
}
};
98. 验证二叉搜索树
给你一个二叉树的根节点 root
,判断其是否是一个有效的二叉搜索树。
有效 二叉搜索树定义如下:
- 节点的左子树只包含 小于 当前节点的数。
- 节点的右子树只包含 大于 当前节点的数。
- 所有左子树和右子树自身必须也是二叉搜索树。
示例 1:
输入:root = [2,1,3]
输出:true
示例 2:
输入:root = [5,1,4,null,null,3,6]
输出:false
解释:根节点的值是 5 ,但是右子节点的值是 4 。
提示:
树中节点数目范围在 [1, 104]
内
-2^31 <= Node.val <= 2^31 - 1
思路:从底往上划范围,判断父节点符不符合要求
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
private:
bool yes = true;
public:
bool isValidBST(TreeNode* root) {
valid(root);
return yes;
}
pair<int, int> valid(TreeNode* root){
if(yes == false) return {};
int min_l, max_l, min_r, max_r, min_a, max_a;
if(root->left == nullptr){
min_a = root->val;
}else{
auto le = valid(root->left);
min_l = le.first;
max_l = le.second;
if(root->val <= max_l){
yes = false;
return {};
}
min_a = min_l;
}
if(root->right == nullptr){
max_a = root->val;
}else{
auto ri = valid(root->right);
min_r = ri.first;
max_r = ri.second;
if(root->val >= min_r){
yes = false;
return {};
}
max_a = max_r;
}
return {min_a, max_a};
}
};
思路:从顶往下判断是否符合,注意数值范围,要用long
class Solution {
private:
bool yes = true;
public:
bool isValidBST(TreeNode* root) {
return valid(root, LONG_MIN, LONG_MAX);
}
bool valid(TreeNode* root, long min_range, long max_range){
if(root == nullptr) return true;
if(root->val >= max_range || root->val <= min_range) return false;
return valid(root->left, min_range, root->val) && valid(root->right, root->val, max_range);
}
};