题目:
给定一个二叉树,判断其是否是一个有效的二叉搜索树。
假设一个二叉搜索树具有如下特征:
- 节点的左子树只包含小于当前节点的数。
- 节点的右子树只包含大于当前节点的数。
- 所有左子树和右子树自身必须也是二叉搜索树。
示例 1:
输入: 2 / \ 1 3 输出: true
示例 2:
输入: 5 / \ 1 4 / \ 3 6 输出: false 解释: 输入为: [5,1,4,null,null,3,6]。 根节点的值为 5 ,但是其右子节点值为 4 。
解题思路:
根据二叉搜索树的定义,我们发现一条规律,如果对该二叉树进行中序遍历,那么得到的是一个递增的序列。那这样的话,是不是需要一个数组来保存这个中序遍历得到的序列? 不用,我们可以设置两个变量 last 和 now,last为当前节点的中序遍历上一个节点的值,now为当前节点的值,这样若存在 now <= last 就不是二叉搜索树。
还有一点需要注意,last的初始值为多少比较好? 一开始我的想法是让last等于INT_MIN,但这样的话,若是中序遍历的第一个节点的值恰好为INT_MIN呢?这样不就满足了 now <= last 判错了吗?所以这里的last的首值必须为第一个节点的值,为保证这一点,应该还要设置一个cnt,用来记录是否是第一个节点,是第一个节点则让last等于它的值。
代码:
1 /** 2 * Definition for a binary tree node. 3 * struct TreeNode { 4 * int val; 5 * TreeNode *left; 6 * TreeNode *right; 7 * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 8 * }; 9 */ 10 class Solution { 11 public: 12 int last,now,cnt; 13 void inOrder(TreeNode* root, int &flag) 14 { 15 if(!root || flag) 16 { 17 return ; 18 } 19 inOrder(root->left, flag); 20 if(cnt == 1) { 21 last = root->val; 22 } 23 else { 24 now = root->val; 25 if(now <= last) { 26 flag = 1; 27 return ; 28 } 29 else 30 { 31 last = now; 32 } 33 } 34 cnt++; 35 inOrder(root->right, flag); 36 } 37 bool isValidBST(TreeNode* root) { 38 if(root == NULL || (root && root->left == NULL && root->right == NULL)) 39 return true; 40 TreeNode* p = root; 41 int flag = 0; 42 cnt = 1; 43 inOrder(root, flag); 44 if(flag == 0) 45 return true; 46 else 47 return false; 48 } 49 };