驗證二叉搜索樹
阿新 • • 發佈:2018-06-10
root tail span 所有結點 stat family blank 若是 遍歷
說實話,樹結構一直是我的弱項,這也體現了我對遞歸這樣的方法不熟(在我看來,樹和遞歸關系很密切)。現在刷題刷到樹相關的題目了。題目如標題:驗證二叉搜索樹。
開始我的思路是:假定當前結點值為k,對於二叉樹中每個結點,判斷其左子樹的值是否小於k,其右子樹的值是否大於k。如果所有結點都滿足該條件,則該二叉樹是一棵二叉搜索樹。但是這是錯的,比如這樣:
10 / 5 15 / 6 20
這棵樹就滿足上面的算法思路,但是這不是二叉搜索樹,因為6小於10;所以換一種思路:
暴力破解: 假定當前結點值為k。對於二叉樹中每個結點,其左子樹所有結點的值必須都小於k,其右子樹所有結點的值都必須大於k。
代碼:
1 class Solution { 2 public: 3 bool isValidBST(TreeNode* root, int min = INT_MIN, int max = INT_MAX) { 4 if (root == nullptr) //終止條件 5 { 6 return true; 7 } 8 return ((Tree_left(root->left, root->val)) && (Tree_Right(root->right, root->val)) && isValidBST(root->left) && isValidBST(root->right));9 } 10 bool Tree_left(TreeNode *root, int val) 11 { 12 if (root == NULL) 13 { 14 return true; 15 } 16 return ((root->val < val) && (Tree_left(root->left, val)) && (Tree_left(root->right, val))); 17 } 18 bool Tree_Right(TreeNode*root, intval) 19 { 20 if (root == NULL) 21 { 22 return true; 23 } 24 return ((root->val > val) && (Tree_Right(root->left, val)) && (Tree_Right(root->right, val))); 25 } 26 int min = INT_MIN, max = INT_MAX; 27 };
但是比較慢,最壞的情況是O(n^2)。所以我參考另一種方法:
中序遍歷:遍歷方向:左節點==>根==>右節點。前面的鏈接是維基百科,若是不能訪問,請戳這裏。
拿前面的那顆樹來說:遍歷之後的結果就是:5,10,6,15,20.可以很清晰的看出來,6在10後面,不滿足從小到大的順序,即:二叉搜索樹的中序遍歷之後的結果是一個從小到大的有序集合。 所以,接下來的事情就比較簡單了:
1 class Solution { 2 public: 3 bool isValidBST(TreeNode* root) { 4 vector<int> v; 5 inOrder(root, v); 6 for (int i = 1; i < v.size(); ++ i){ 7 if (v[i - 1] >= v[i]) 8 return false; 9 } 10 return true; 11 } 12 private: 13 void inOrder(TreeNode* root, vector<int>& v){ 14 if (root == nullptr) return; 15 inOrder(root->left, v); 16 v.push_back(root->val); 17 inOrder(root->right, v); 18 } 19 20 }; 21 static int _____ = [](){ 22 std::ios::sync_with_stdio(false); 23 cin.tie(NULL); 24 return 0; 25 }();
inOrder()函數實現中序遍歷,接下來就是一個比較循環。代碼是別人寫的:來源LeetCode:初級算法:樹:驗證搜索二叉樹。
參考:https://blog.csdn.net/sgbfblog/article/details/7771096
驗證二叉搜索樹