Description:
输入一个整形数组,表示一颗满二叉树,判断是否是一颗二叉搜索树。
满二叉树:一颗二叉树,除了最后一层没有子节点,其他节点都有两个子节点。
二叉搜索树:一颗二叉树,若左子树不空,则左子树的所有节点值都小于它的根节点值;若右子树不空,则右子树的所有节点值都大于它的根节点值,且它的左右子树分别是二叉搜索树。
题目链接:牛客网链接
Analysis:
根据输入序列建立二叉树,再根据二叉搜索树特点,判断是否是二叉搜索树。
特点1:定义中的特点,左右子树大小关系;特点2:延伸特点,中序遍历二叉搜索树的序列是递增排序。
Solution:
bool IsBST(TreeNode* root) {
if (root == nullptr)
return true;
if (root->left && root->left->val >= root->val)
return false;
if (root->right && root->right->val <= root->val)
return false;
return IsBST(root->left) && IsBST(root->right);
}
开始写成这样,不能覆盖所有case,比如10,5,15,3,11,13,18,正确判断是false,遗漏的点是左子树所有节点都小于它的根节点值,右子树所有节点都大于它的根节点。
修正解决: 判断根节点的左子树最大值小于等于根节点,右子树的最小值大于等于根节点,再递归左右子树,这样会有重复计算的问题。
再修正解决1: 利用二叉搜索树特点,左子树节点取值范围(INT_MIN, root->val),右子树节点取值范围(root->val, INT_MAX),如果节点不在这个范围,则报错。
bool IsBST2(TreeNode* root) {
return helper(root, INT_MIN, INT_MAX);
}
bool helper(TreeNode* root, int min, int max) {
if (root == nullptr)
return true;
if (root->val <= min || root->val >= max)
return false;
return helper(root->left, min, root->val) && helper(root->right, root->val, max);
}
再修正解决2: 中序遍历建立的二叉搜索树,判断是否是递增序列。
最后通过的完整代码:
#include <vector>
#include <queue>
#include <iostream>
using namespace std;
struct TreeNode {
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int value) : val(value), left(nullptr), right(nullptr) {
}
};
TreeNode* BuildTree(vector<int>& nums) {
int len = nums.size();
if (len == 0)
return nullptr;
TreeNode* root = new TreeNode(nums[0]);
TreeNode* cur = root, *temp = nullptr;
queue<TreeNode *> que;
que.push(cur);
for (int i = 1; i < len; i ++) {
temp = new TreeNode(nums[i]);
if (i % 2) {
cur = que.front();
cur->left = temp;
que.pop();
} else {
cur->right = temp;
}
que.push(temp);
}
return root;
}
void Inorder(TreeNode* root, vector<int>& seqs) {
if (root == nullptr)
return;
Inorder(root->left, seqs);
seqs.push_back(root->val);
Inorder(root->right, seqs);
}
bool IsBst(TreeNode* root) {
vector<int> seqs;
Inorder(root, seqs);
for (int i = 1; i < seqs.size(); i ++) {
if (seqs[i - 1] >= seqs[i])
return false;
}
return true;
}
int main(void) {
vector<int> nums;
int n;
char c;
while (cin >> n) {
nums.push_back(n);
cin >> c;
}
TreeNode* root = BuildTree(nums);
if (IsBst(root)) {
cout << "True" << endl;
} else {
cout << "False" << endl;
}
return 0;
}
References:
[1] https://blog.csdn.net/sgbfblog/article/details/7771096
[2] https://cloud.tencent.com/developer/article/1531775