该题的解法有很多种:
- 使用递归来解,递归遍历每个节点,看结点的左子树的所有结点是不是比该结点小,右子树的所有节点是不是比该结点大;
- 使用中序遍历得到树的遍历结果,检查遍历结果是不是从小到大的顺序排列;
- 保存遍历过程中的前驱结点,检查当前结点值是不是比前驱结点大;
1. 递归解法
class Solution {
public:
bool isValidBST(TreeNode* root) {
if(!root || (!root->left && !root->right))
return true;
return isValidBST(root, LONG_MIN, LONG_MAX);
}
bool isValidBST(TreeNode *root, long int min, long int max) {
if(!root) return true;
return root->val > min && root->val < max && isValidBST(root->left, min, root->val) && isValidBST(root->right, root->val, max);
}
};
2. 先遍历后检查
class Solution {
public:
bool isValidBST(TreeNode* root) {
if (!root) return true;
vector<int> vals;
inorder(root, vals);
for (int i = 0; i < vals.size() - 1; ++i) {
if (vals[i] >= vals[i + 1]) return false;
}
return true;
}
void inorder(TreeNode* root, vector<int>& vals) {
if (!root) return;
inorder(root->left, vals);
vals.push_back(root->val);
inorder(root->right, vals);
}
};
3. Morris解法
class Solution {
public:
bool isValidBST(TreeNode* root) {
TreeNode *p = root;
TreeNode *pre = nullptr;
bool res = true;
while(p) {
if(p->left) {
TreeNode *temp = p->left;
while(temp->right != nullptr && temp->right != p) {
temp = temp->right;
}
if(temp->right == nullptr) {
temp->right = p;
p = p->left;
} else {
temp->right = nullptr;
if(pre && pre->val >= p->val)
res = false; // 不能直接返回false,否则线索指针还没被清除掉
pre = p;
p = p->right;
}
} else {
if(pre && pre->val >= p->val)
res = false; // 不能直接返回false,否则线索指针还没被清除掉
pre = p;
p = p->right;
}
}
return res;
}
};
参考资料: