Validate Binary Search Tree 验证二叉搜索树

给定一个二叉树,判断其是否是一个有效的二叉搜索树。

一个二叉搜索树具有如下特征:

  • 节点的左子树只包含小于当前节点的数。
  • 节点的右子树只包含大于当前节点的数。
  • 所有左子树和右子树自身必须也是二叉搜索树。

示例 1:

输入:
    2
   / \
  1   3
输出: true

示例 2:

输入:
    5
   / \
  1   4
     / \
    3   6
输出: false
解释: 输入为: [5,1,4,null,null,3,6]。
     根节点的值为 5 ,但是其右子节点值为 4 。

思路

这道题用递归的方法,比较当前节点是否比左节点的值大,是否比右节点的值小,如果是就继续递归左右子树。写完自信满满,而然发现不通过,看了test case发现有如下的情况:

    5
   / \
  1   8
     / \
    3   9

上述方法无法判断跨越了超过1层的情况。所以想其他方法。

那么能不能dfs来保存左右子树的最大最小值呢?即每次保存左子树的最大值,右子树的最小值。判断当前节点的值是否大于左子树最大,小于右子树最小,然后通过公式:

left_max=max(left_max,root->val)
right_min=min(right_min,root->val)

来更新然后回传给父节点。但是这样也是不行的,连最简单的test都通不过!!!!如下:

    2
   / \
  1   3

当判断节点1时,left_max和right_min都被更新成了1,当用中序遍历遍历到2的右子树3节点时(顺序1-2-3),通过公式更新right_min时依然会更新为1而不是3,因为右子树在更新时会带着左子树的信息,无法独立更新,如果在递归右子树前把left_max和right_min赋值为初始化值,就没有了判断超过两层的能力。递归函数本身无法区分左右子树,对函数签名而言,只要满足要求就进入主函数。

所以参考了网上的两个方法:中序遍历来判断和另一种递归方法(逐步缩小范围)。

1:中序遍历

由于左<根<右,不存在相等的情况,所以保存上次遍历的值,看这次的值是否大于上次即可。

所以不会出现这种情况:

    2       2
   /         \
  2           2   

这两种情况如果题目(左<=根<右),那么是无法区别的,因为中序遍历出来是相同的。

代码:

void isValidBSTCore(TreeNode* root, TreeNode* &tmp,bool &flag, TreeNode* true_root) {
	if (!flag || !root) {
		return;
	}
	isValidBSTCore(root->left, tmp,flag,true_root);
	if (tmp) {
		if (root->val <= tmp->val) {
			flag = false;
			return;
		}
	}
	tmp = root;
	isValidBSTCore(root->right, tmp, flag, true_root);
}
bool isValidBST(TreeNode* root) {
	if (!root) {
		return true;
	}
	TreeNode* tmp = nullptr;
	bool flag = true;
	isValidBSTCore(root, tmp, flag, root);
	return flag;
}

2:递归逐步缩小范围,从父向子判断,首先初始化mm=long_min,mx=long_max,如果根节点值为mid,那么左子树的所有节点的范围为[mm,mid),右子树的所有节点范围为(mid,mx],以此类推。因为一开始的边界条件会判断当前节点是否在范围内,所以范围绝对是越来越小的,这样就很好解决了跨级判断的问题。还是如下图的例子,看图每个节点的范围就很清楚:


通过一层层缩小范围,可以找到3不满足bst条件。

代码:

bool isValidBSTCore(TreeNode* root, long mm, long mx) {
	if (!root) {
		return true;
	}
	if (root->val<=mm || root->val>=mx) {
		return false;
	}
	return isValidBSTCore(root->left, mm, root->val) && isValidBSTCore(root->right, root->val, mx);
}
bool isValidBST(TreeNode* root) {
	if (!root) {
		return true;
	}
	return isValidBSTCore(root, LONG_MIN, LONG_MAX);
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值