代码随想录 | Day22 | 二叉树:二叉搜索树中的搜索&&验证二叉搜索树
主要学习内容:
二叉搜索树的性质:中序遍历是递增序列
700.二叉搜索树中的搜索
700. 二叉搜索树中的搜索 - 力扣(LeetCode)
解法:二分查找
**思路:**如果当前结点t->val大于val就去遍历左子树
如果小于就去遍历右子树
找到了就返回当前结点就是了
1.函数参数和返回值
| 1
 | TreeNode* tra(TreeNode *t,int val)
 | 
t为当前节点,val为目标值
2.终止条件
| 12
 
 | if(t==nullptr || t->val==val)return t;
 
 | 
为空或者找到了都是返回本身
3.本层代码逻辑
其实就是二分查找的三种情况,找到了答案和大于小于搜索值
这三种情况也是互斥的,遍历左子树以后就不会去遍历右子树
| 12
 3
 4
 5
 6
 
 | if(t==nullptr || t->val==val)return t;
 else if(t->val>val)
 return tra(t->left,val);
 else
 return tra(t->right,val);
 
 | 
完整代码:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 
 | class Solution {public:
 TreeNode* tra(TreeNode *t,int val)
 {
 if(t==nullptr || t->val==val)
 return t;
 else if(t->val>val)
 return tra(t->left,val);
 else
 return tra(t->right,val);
 }
 TreeNode* searchBST(TreeNode* root, int val) {
 return tra(root,val);
 }
 };
 
 | 
总体来说比较简单
98.验证二叉搜索树
98. 验证二叉搜索树 - 力扣(LeetCode)
解法:中序遍历
**思路1:**首先要知道,二叉搜索树的性质之一是中序遍历会形成一个有序序列
理所当然,通过中序遍历,把树转化为数组,然后分析判断数组中有没有重复元素就行
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 
 | class Solution {private:
 vector<int> vec;
 void traversal(TreeNode* root) {
 if (root == NULL) return;
 traversal(root->left);
 vec.push_back(root->val);
 traversal(root->right);
 }
 public:
 bool isValidBST(TreeNode* root) {
 vec.clear();
 traversal(root);
 for (int i = 1; i < vec.size(); i++) {
 
 if (vec[i] <= vec[i - 1]) return false;
 }
 return true;
 }
 };
 
 | 
**思路二:**在中序遍历的时候顺手比较一下,看看序列是否是递增的。即设置一个最大值,中序遍历过程中只会遇到更大的值,遇到更大的值说明是正确的,更新他就行,如果遇到了小于等于的说明这并不是二叉搜索树,直接结束验证返回false
1.函数参数和返回值
| 12
 
 | long long maxVal=LONG_MIN;bool tra(TreeNode *t)
 
 | 
t为当前节点,maxval为最大值,用来验证序列是否递增,设置为long的最小值是因为测试数据里面有int的最小值
2.终止条件
| 12
 3
 4
 5
 6
 
 | if(t==nullptr)return true;
 if(t->val>maxVal)
 maxVal=t->val;
 else
 return false;
 
 | 
为空返回true,因为它没有破坏递增的序列
当前结点小于了最大值,那么直接失败
3.本层代码逻辑
中序遍历,典型的左中右,可以判断序列是否递增
| 12
 3
 4
 5
 6
 7
 
 | bool left=tra(t->left,maxVal);if(t->val>maxVal)
 maxVal=t->val;
 else
 return false;
 bool right=tra(t->right,maxVal);
 return left&&right;
 
 | 
完整代码:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 
 | class Solution {public:
 long long maxVal=LONG_MIN;
 bool tra(TreeNode *t)
 {
 if(t==nullptr)
 return true;
 bool left=tra(t->left);
 if(t->val>maxVal)
 maxVal=t->val;
 else
 return false;
 bool right=tra(t->right);
 return left&&right;
 }
 bool isValidBST(TreeNode* root) {
 return tra(root);
 }
 };
 
 | 
错误代码
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 
 | class Solution {public:
 bool tra(TreeNode *t,int maxVal)
 {
 if(t==nullptr)
 return true;
 bool left=tra(t->left,maxVal);
 if(t->val>maxVal)
 maxVal=t->val;
 else
 return false;
 bool right=tra(t->right,maxVal);
 return left&&right;
 }
 bool isValidBST(TreeNode* root) {
 return tra(root,-1);
 }
 };
 
 | 
错误点:
1.使用了参数,这样的话,使用中序遍历当左子树遍历完了以后不会更新最大的val值,if判断的还是会是本层递归函数里的没有更新的maxval,无法判断序列是否递增
测试失败案例:
root=[1,1];
2.没有注意到测试数据最小值,应该传入LONG_MIN.