LeetCode刷题日记之搜索二叉树中的众数

45 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第19天,点击查看活动详情
1.二叉搜索树的最小绝对差

题目描述

image.png

解题思路

二叉搜索树的中序排列是一个递增的数组,求任意两个不同节点之间的最小差值,一定是中序遍历的相邻两个节点之间,所以使用中序遍历,求出每两个节点之间的差值,每次递归更新最小值即可

var getMinimumDifference = function(root) {
  // 二叉搜索树中序遍历是一个有序数组
    let result = Infinity;
    let pre = null
    var traversal = function(node) {
        if(node == null) {
            return
        }

        traversal(node.left) // 左

        if(pre != null) {
            result = Math.min(result,node.val - pre.val) // 求最小值
        }
        pre = node; // 中

        traversal(node.right) // 右

    }

    traversal(root)

    return result
};

2.二叉搜索树中的众数

题目描述

image.png

解题思路

本题需要注意的是,题目明确说明,众数可能不止有一个,这一点需要特别注意。
递归法,使用中序遍历,统计每个节点值出现的次数
1.确认递归参数及返回值,本题采用全局变量,没有返回值,参数为递归节点
2.确认递归终止条件,当遍历节点为空时,直接返回
3.确认单层处理逻辑

   traversal(node.left) // 左

        if(pre == null) {
            count = 1 // 第一个节点
        } else if(pre.val == node.val) {
            count ++ //与前一个数相同
        } else {
            count = 1; //与前一个不相同  从新开始计数
        }

        pre = node;
        if(max == count) {
            result.push(node.val) // 等于计数等于最大值  直接将节点加入结果中
        }

        if(count > max) { // 如果计数大于最大值
            max = count;
            result = []; // 清除之前添加的最大值
            result.push(node.val)
        }
        
        traversal(node.right)

整体代码

var findMode = function(root) {
       // 树的节点数至少为1所以众数的最小值为1
    let max = 0;
    let pre = null;
    let count = 0;
    let result = []
    var traversal = function(node) {
        if(node == null) {
            return 
        }

        traversal(node.left) // 左

        if(pre == null) {
            count = 1 // 第一个节点
        } else if(pre.val == node.val) {
            count ++ //与前一个数相同
        } else {
            count = 1; //与前一个不相同  从新开始计数
        }

        pre = node;
        if(max == count) {
            result.push(node.val) // 等于计数等于最大值  直接将节点加入结果中
        }

        if(count > max) { // 如果计数大于最大值
            max = count;
            result = []; // 清除之前添加的最大值
            result.push(node.val)
        }
        
        traversal(node.right) // 右
    }

    traversal(root) 

    return result
};

本题还可以采用迭代法解决,同样使用中序遍历,关键处理逻辑相同

var findMode = function(root) {
    let stack = []
    let result = []
    let max = 0;
    let count = 0;
    let pre = null;
    let cur = root;
    while(cur!==null || stack.length) {
        if(cur !== null) { // 不为空时 将当前节点入栈
           stack.push(cur)
           cur = cur.left; // 左
        } else{
            cur = stack.pop() // 中

            if(pre == null) {
               count = 1 // 第一个节点
            } else if(pre.val == cur.val) {
                count ++ //与前一个数相同
            } else {
                count = 1; //与前一个不相同  从新开始计数
            }

            if(max == count) {
                result.push(cur.val) // 等于计数等于最大值  直接将节点加入结果中
            }

            if(count > max) { // 如果计数大于最大值
                max = count;
                result = []; // 清除之前添加的最大值
                result.push(cur.val)
            }

            pre = cur;
            cur = cur.right  // 右
        }
    }

    return result
};