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: 中序遍歷建立的二叉搜索樹,判斷是否是遞增序列。
bool IsBST(TreeNode* root) {
vector<int> sort_order;
Inorder(root, sort_order);
for (int i = 0; i < sort_order.size() - 1; i ++)
if (sort_order[i] >= sort_order[i + 1])
return false;
return true;
}
void Inorder(TreeNode* root, vector<int>& sort_order) {
if (root == nullptr)
return;
sort_order.push_back(root->val);
Inorder(root->left, sort_order);
Inorder(root->right, sort_order);
}
最後通過的完整代碼:
References:
[1] https://blog.csdn.net/sgbfblog/article/details/7771096
[2] https://cloud.tencent.com/developer/article/1531775