兄弟们,我黄某人又回来了!!!!
题目:题目链接
思路:题目大意就是让你判断是否是一个合法的BST。树的话一般就是递归,只有亿点点难吧。
方法一 递归
对于一个结点A,其左子树所有结点都要小于A的值,其右子树所有结点都要大于A的值。所以对于左子树而言其上界是A的值,右子树而言其下界是A的值。晕了晕了。
别急!这是不是就是说我递归做的话参数最起码要有两个,结点,上界和下界。那么当前结点只要在上界和下界之间就是合法的。那么可以搞出代码:
/**
* 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:
typedef long long ll;
bool dfs(TreeNode* root, ll min, ll max) {// min为上界,max为下界
if (!root) return true;
if (root->val <= min || root->val >= max) return false;//不在上下界中就不合法
return dfs(root->left, min, root->val) && dfs(root->right, root->val, max);//对左右子树递归操作
}
bool isValidBST(TreeNode* root) {
return dfs(root, LLONG_MIN, LLONG_MAX);//不能用INT_MAX哦
}
};
注意哦这里不能用INT_MAX哦,因为有一组样例就是[2^31-1]。而初始上下界的作用就是判断根节点是否合法,根节点肯定不管怎样都合法,所以初始上下界可以给大一点。
这个递归代码短小精悍啊,真的是妙啊!
方法二 中序遍历
我们再想一想,一个合法的BST,其中序遍历一定是递增的吧。因为BST的特性就是左儿子的值>父结点的值>右儿子的值。那么中序遍历呗。也别迭代了,直接递归吧。看代码:
class Solution {
public:
typedef long long ll;
ll pre = LLONG_MIN;//先前结点的值。
bool dfs(TreeNode* root) {
if (!root) return true;
bool left_is_valid = dfs(root->left);//判断左子树合法吗
if (pre >= root->val) return false;//当前结点的值一定要大于先前结点的值,因为是递增的序列。
pre = root->val;//更新pre,为当前结点的值。
bool right_is_valid = dfs(root->right);
return left_is_valid && right_is_valid;//判断右子树合法吗
}
bool isValidBST(TreeNode* root) {
return dfs(root);
}
};
这说实在的太妙了,真的。看到树,看到递归解法,就是感觉太漂亮了,太妙了。我啥时候有这么厉害啊!
加油加油加油加油加油!!!!!你是最棒的!!加油哦!!