代码随想录day21| 二叉树part07(530、501、236)

87 阅读3分钟

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

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

差值是一个正数,其数值等于两值之差的绝对值。

  示例 1:

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

示例 2:

输入: root = [1,0,48,null,null,12,49]
输出: 1

思路:

  1. 二叉搜索树,所以差值最小为1(不存在0)
  2. 中序遍历时,最小差值 一定出现在相邻遍历的接点
/**
* @param {TreeNode} root
* @return {number}
*/
var getMinimumDifference = function (root) {

   let min = Infinity
   let preVal;
   const inorder = (root) => {
       if (root === null || min === 1) return
       root.left && inorder(root.left)
       // 这里要判断undefined, 防止0 被刷掉
       if (preVal != undefined) {
           min = Math.min(Math.abs(root.val - preVal), min)
       }
       preVal = root.val
       root.right && inorder(root.right)
   }
   inorder(root)
   return min
};

501. 二叉搜索树中的众数

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

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

假定 BST 满足如下定义:

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

 

示例 1:

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

示例 2:

输入: root = [0]
输出: [0]

思路

基于二叉搜索树的特征,中序遍历是相同值的节点一定相邻

/**
 * @param {TreeNode} root
 * @return {number[]}
 */
var findMode = function(root) {
    let max = [0,0]  // val, times
    let pre = [null, 0]
    let res = []
    const inorder = (node)=>{
        if(node === null) return 
        node.left && inorder(node.left)
        if(pre[0] != null){
       
            pre[1] = node.val === pre[0] ? pre[1] + 1: 1
            pre[0] = node.val

             if(pre[1] > max[1]){
                max = [...pre]
                res = [pre[0]]
            }else if( pre[1] === max[1]){
                max = [...pre]
                res.push(pre[0])
            }

        }else{
            pre = [node.val, 1]
            max = [node.val, 1]
            res = [node.val]
        }
        
        node.right && inorder(node.right)
    }
    inorder(root)
    return res
};

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

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

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

 

示例 1:

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

示例 2:

输入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4
输出: 5
解释: 节点 5 和节点 4 的最近公共祖先是节点 5 。因为根据定义最近公共祖先节点可以为节点本身。

示例 3:

输入: root = [1,2], p = 1, q = 2
输出: 1

思路

  1. 先序遍历,如果先访问的p,那么公共祖先一定不能为p的子节点,也就是说没必要向下访问了
  2. 这时去访问另一棵子树,如果包含q,则公共祖先为对应的root,如果不包含,则祖先为p
/**
 * @param {TreeNode} root
 * @param {TreeNode} p
 * @param {TreeNode} q
 * @return {TreeNode}
 */
var lowestCommonAncestor = function(root, p, q) {
    if(root === null || root === p || root ===q) return root
    const left  = lowestCommonAncestor(root.left, p ,q)
    const right  = lowestCommonAncestor(root.right, p ,q)
    if(left && right){
        return root
    }
    return left || right
};