代码随想录算法训练营第二十一天| 530. 二叉搜索树的最小绝对差|501. 二叉搜索树中的众数|236. 二叉树的最近公共祖先

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

题目:给你一个二叉搜索树的根节点 root ,返回 树中任意两不同节点值之间的最小差值 。

差值是一个正数,其数值等于两值之差的绝对值。
示例一:代码随想录算法训练营第二十一天| 530. 二叉搜索树的最小绝对差|501. 二叉搜索树中的众数|236. 二叉树的最近公共祖先_第1张图片

输入:root = [4,2,6,1,3]
输出:1

思路:中序递归遍历,双指针,通过一个指针一直指向前一个遍历的元素,通过两个相邻元素的比较得到最小差值。

C#代码:

public class Solution {
    int minValue = int.MaxValue;
    TreeNode previous = null;
    public int GetMinimumDifference(TreeNode root) {
        Traversal(root);
        return minValue;
    }
    public void Traversal(TreeNode root){
        if(root== null) return;
        //左
        GetMinimumDifference(root.left);
        //中
        if(previous != null){
        	//minValue = Math.Min(minValue,root.val-previous.val);
            if(minValue>root.val-previous.val){
                minValue = root.val-previous.val;
            }
        }
        previous = root;
        //右
        GetMinimumDifference(root.right);
    }
}

501. 二叉搜索树中的众数

题目:给你一个含重复值的二叉搜索树(BST)的根节点 root,找出并返回 BST 中的所有 众数(即,出现频率最高的元素)。

如果树中有不止一个众数,可以按 任意顺序 返回。

假定 BST 满足如下定义:

  • 结点左子树中所含节点的值 小于等于 当前节点的值
  • 结点右子树中所含节点的值 大于等于 当前节点的值
  • 左子树和右子树都是二叉搜索树

示例一:代码随想录算法训练营第二十一天| 530. 二叉搜索树的最小绝对差|501. 二叉搜索树中的众数|236. 二叉树的最近公共祖先_第2张图片

输入:root = [1,null,2,2]
输出:[2]

思路:如果不是二叉搜索树,最直观的方法一定是把这个树都遍历了,用map统计频率,把频率排个序,最后取前面高频的元素的集合。
但这道题目是二叉搜索树,它中序遍历就是有序的,遍历有序数组的元素出现频率,从头遍历,那么一定是相邻两个元素作比较,然后就把出现频率最高的元素输出就可以了。
如果 频率count 等于 maxCount(最大频率),当然要把这个元素加入到结果集中。
频率count 大于 maxCount的时候,不仅要更新maxCount,而且要清空结果集。

C#代码

public class Solution {
    int count = 0,maxCount = 0;
    TreeNode pre = null;
    List<int> list = new List<int>();
    public int[] FindMode(TreeNode root) {
      Traversal(root);
      return list.ToArray();
    }
    public void Traversal(TreeNode root){
      if(root == null) return;
      Traversal(root.left);
      // 计数
      if(pre==null||pre.val!=root.val) count = 1;
      else count++;
      // 更新结果以及maxCount
      if(count==maxCount){
          list.Add(root.val);
        }else if(count >maxCount){
          maxCount = count;
          list.Clear();
          list.Add(root.val);
        }
      pre = root;
      Traversal(root.right);
    }
}

236. 二叉树的最近公共祖先

题目:给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。

百度百科中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”

提示

  • 树中节点数目在范围 [2, 105] 内。
  • -109 <= Node.val <= 109
  • 所有 Node.val 互不相同 。
  • p != q
  • p 和 q 均存在于给定的二叉树中。

示例一:代码随想录算法训练营第二十一天| 530. 二叉搜索树的最小绝对差|501. 二叉搜索树中的众数|236. 二叉树的最近公共祖先_第3张图片

输入:root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
输出:3
解释:节点 5 和节点 1 的最近公共祖先是节点 3 。

思路:
首先最容易想到的一个情况:如果找到一个节点,发现左子树出现结点p,右子树出现节点q,或者 左子树出现结点q,右子树出现节点p,那么该节点就是节点p和q的最近公共祖先。
需要从底向上遍历,那么二叉树,只能通过后序遍历(即:回溯)实现从底向上的遍历方式。
在回溯的过程中,必然要遍历整棵二叉树,即使已经找到结果了,依然要把其他节点遍历完,因为要使用递归函数的返回值(也就是代码中的left和right)做逻辑判断。
要理解如果返回值left为空,right不为空为什么要返回right,为什么可以用返回right传给上一层结果。

C#代码

public class Solution {
    public TreeNode LowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if(root==null||root==p||root==q) return root;
        // 后序遍历:左、右、中
        TreeNode leftTree = LowestCommonAncestor(root.left,p,q);
        TreeNode rightTree = LowestCommonAncestor(root.right,p,q);
        //中
        // 若未找到节点 p 或 q
        if(leftTree==null&&rightTree==null) return null;
        // 若找到一个节点
        else if(leftTree!=null&&rightTree==null) return leftTree;
        else if(leftTree==null&&rightTree!=null) return rightTree;
        // 若找到两个节点
        else return root;
    }
}

你可能感兴趣的:(算法,算法)