LeetCode 98 验证二叉搜索树 -- 递归法和迭代法

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/validate-binary-search-tree


题意:

给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。

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

示例 1:
LeetCode 98 验证二叉搜索树 -- 递归法和迭代法_第1张图片
输入:root = [2,1,3]
输出:true

示例 2:
LeetCode 98 验证二叉搜索树 -- 递归法和迭代法_第2张图片
输入:root = [5,1,4,null,null,3,6]
输出:false
解释:根节点的值是 5 ,但是右子节点的值是 4 。

提示:
树中节点数目范围在[1, 104] 内
-231 <= Node.val <= 231 - 1


参考文章

思路:

做这道题之前,首先要理解二叉搜索树的概念与特点。

其次,做这道题的时候容易陷入一个陷阱,就是只单纯地将中间节点与左节点和右节点进行比较,直接返回结果。我第一次写这道题时候的代码是:

class Solution {
	public boolean isValidBST(TreeNode root) {
		boolean ans = true;
		if (root.left != null) ans = ans && root.val > root.left.val && isValidBST(root.left);
		if (root.right != null) ans = ans && root.val < root.right.val && isValidBST(root.right);
		return ans;
	}
}

直接就WA了,解答错误的测试用例是:[5,4,6,null,null,3,7],预期结果是false,而代码返回的结果是true。这个测试用例所形成的树是:
LeetCode 98 验证二叉搜索树 -- 递归法和迭代法_第3张图片
在这个测试用例中,每个节点都满足左节点小于中间节点、右节点大于中间节点,所以代码返回的结果是true,但是实际上这个测试用例并不满足二叉搜索树的定义,节点值为3的节点是不应该出现在这个位置的

递归法:

这道题的第一个做法是,利用二叉搜索树的特点,我们直接使用中序遍历得到二叉搜索树节点的有序序列,判断这个有序序列是否是真的有序即可

以上做法的Java代码:

class Solution {
	private List<Integer> list;

	private void travel(TreeNode node) {
		if (node == null)
			return;
		travel(node.left);
		list.add(node.val);
		travel(node.right);
	}

	public boolean isValidBST(TreeNode root) {
		list = new ArrayList<>();
		travel(root);
		for (int i = 0; i < list.size() - 1; i++) {
			if (list.get(i) >= list.get(i + 1))
				return false;
		}
		return true;
	}
}

但其实我们也可以不将遍历结果转变为数组进行判断,可以在递归获取遍历序列的过程中直接进行判断是否有序。

以上做法的Java代码:

class Solution {
	TreeNode rnNode;//记录当前遍历到的节点
	public boolean isValidBST(TreeNode root) {
		if (root == null) return true;
		boolean left = isValidBST(root.left);
		if (rnNode != null && rnNode.val >= root.val) return false;
		rnNode = root;
		boolean right = isValidBST(root.right);
		return left && right;
	}
}

迭代法:

迭代法其实就是不用递归方法来遍历,而是改用一个栈来实现中序遍历,即迭代的方式,思路与上面的递归法是一样的,都是在中序遍历的过程中直接进行判断是否有序

以上做法的Java代码:

class Solution {
	public boolean isValidBST(TreeNode root) {
		TreeNode rnNode = null;// 记录当前中序遍历序列的最后一个节点
		TreeNode curNode = root;
		Deque<TreeNode> deque = new LinkedList<>();
		while (curNode != null || !deque.isEmpty()) {
			if (curNode != null) {
				deque.push(curNode);
				curNode = curNode.left;
			} else {
				curNode = deque.poll();
				if (rnNode != null && curNode.val <= rnNode.val)
					return false;
				rnNode = curNode;
				curNode = curNode.right;
			}
		}
		return true;
	}
}

你可能感兴趣的:(LeetCode刷题笔记,#,二叉树类题目,leetcode,深度优先,算法)