1. 二叉搜索树中的搜索

二叉搜索树中的搜索
给定二叉搜索树(BST)的根节点 root 和一个整数值 val。
你需要在 BST 中找到节点值等于 val 的节点。 返回以该节点为根的子树。 如果节点不存在,则返回 null 。

1.1 递归

一开始以为很难,无从下手,但是题目已经规定了这是二叉搜索树,意味着将元素按照中序排列,就是一个有序的数组/链表,寻找目标val,有三种结果:

  1. 等于val,那么直接输出根节点
  2. 小于val,目标val在当前节点左边
  3. 大于val,目标在val右边
public TreeNode searchBST(TreeNode root, int val) {if(root==null || val == root.val) return root;return val<root.val ? searchBST(root.left,val) : searchBST(root.right,val);}

1.2 迭代

思路都是一样的

 public TreeNode searchBST(TreeNode root, int val) { while(root!=null && val!=root.val){root= val< root.val?root.left:root.right; } return root;}

2. 验证二叉搜索树

98. 验证二叉搜索树
给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。
有效 二叉搜索树定义如下:
节点的左子树只包含 小于 当前节点的数。
节点的右子树只包含 大于 当前节点的数。
所有左子树和右子树自身必须也是二叉搜索树。

2.1 递归

官方的递归是重写了一个方法,先定义两个值,分别是最小的Integer和最大的Integer,那么这个节点的值一定是在这个范围内的,然后递归将子树的值分别和最小和最大的值比较,然后返回,只不过优点麻烦。
这里可以采取一个简便方法,将最小值先定义在外面,然后先对左子树递归调用 isValidBST,再判断当前节点值是否大于中序遍历的前一个节点的值,如果不大于,则返回 false,即不满足 BST 的条件。最后将当前节点的值赋给 pre 变量,并对右子树递归调用 isValidBST。

class Solution {// 里面会采用integer的最大值,会不通过long pre = Long.MIN_VALUE;public boolean isValidBST(TreeNode root) { if(root == null) return true; // 左子树元素不满足 if(!isValidBST(root.left)){ return false; }// 当前节点小于等于中序遍历的前一个节点 if(root.val<= pre){ return false; } pre = root.val; return isValidBST(root.right);}}

2.2 迭代

二叉搜索树的中序遍历,如果能够满足条件,那么就是有序的,只需要判断当前的值是否小于之前节点的值。

public boolean isValidBST(TreeNode root) { Deque<TreeNode> stack = new LinkedList<>(); // 存储前一个节点元素值 double inorder = -Double.MAX_VALUE;while(!stack.isEmpty() || root!=null){while(root!=null){stack.push(root);root=root.left;}root = stack.pop();if(root.val<=inorder){return false;}inorder = root.val;root=root.right;}return true;}

3. 二叉搜索树的最小绝对差

二叉搜索树的最小绝对差

给你一个二叉搜索树的根节点 root ,返回 树中任意两不同节点值之间的最小差值 。
差值是一个正数,其数值等于两值之差的绝对值。

3.1 递归

依然是先保留前一个节点的值,然后进行中序遍历,比较前一个值与当前值的差是否小于最小值,小于就替换。

class Solution {// 上一个节点的值int pre;// 结果int ans;public int getMinimumDifference(TreeNode root) {ans = Integer.MAX_VALUE;pre=-1;dfs(root);return ans;}public void dfs(TreeNode root){if(root==null){return;}// 左dfs(root.left);// 中if(pre == -1){pre = root.val;}else{ans = Math.min(ans,root.val-pre);pre=root.val;}// 右dfs(root.right);}}

3.2 迭代,中序遍历

一开始就是想的迭代法,但是轮到自己做就有点绕,尤其是在类里定义变量,然后方法里面使用,做法都差不多。

class Solution {// 记录前一个节点TreeNode pre;Stack<TreeNode> stack;public int getMinimumDifference(TreeNode root) { if(root==null) return 0; TreeNode cur = root; stack = new Stack<>(); int res = Integer.MAX_VALUE; while(cur!=null || !stack.isEmpty()){ // 当前节点不为空 if(cur!=null){ stack.push(cur); // 左 cur=cur.left; // 当前节点为空 }else{ cur=stack.pop(); // 中 if(pre!=null){ res=Math.min(res,cur.val-pre.val); } pre=cur; // 右 cur=cur.right; } } return res;}}