501.二叉搜索树中的众数

给定一个有相同值的二叉搜索树(BST),找出 BST 中的所有众数(出现频率最高的元素)。

假定 BST 有如下定义:

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

例如:

给定 BST [1,null,2,2],

501. 二叉搜索树中的众数

返回[2].

提示:如果众数超过1个,不需考虑输出顺序

进阶:你可以不使用额外的空间吗?(假设由递归产生的隐式调用栈的开销不被计算在内)

思路:

注:如果不是二叉搜索树,而是普通二叉树,方法为:

先把树全部遍历一遍,用什么顺序遍历都可以,统计元素频率,把统计出来的出现频率(map中的value排序)。

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
from collections import defaultdict

class Solution:
    def searchBST(self, cur, freq_map):
        if cur is None:
            return
        freq_map[cur.val] += 1  # 统计元素频率
        self.searchBST(cur.left, freq_map)
        self.searchBST(cur.right, freq_map)

    def findMode(self, root):
        freq_map = defaultdict(int)  # key:元素,value:出现频率
        result = []
        if root is None:
            return result
        self.searchBST(root, freq_map)
        max_freq = max(freq_map.values())
        for key, freq in freq_map.items():
            if freq == max_freq:
                result.append(key)
        return result

二叉搜索树:

双指针,中序遍历

cur如果和pre的value相等,count += 1,

直到cur与pre不相等,count = 1,重新来。

如果count等于maxCount(最大频率),把这个元素加入到结果集中。

当频率count大于maxCount的时候,不仅要更新maxCount,而且要清空结果集,因为结果集之前的元素都失效了。把新的元素加入到结果集中。

class Solution:
    def __init__(self):
        self.maxCount = 0  # 最大频率,用于记录BST中某个元素出现的最大频率
        self.count = 0  # 当前元素的频率计数
        self.pre = None  # 记录上一个遍历的节点
        self.result = []  # 存储出现频率最高的元素

    def searchBST(self, cur):
        if cur is None:
            return

        self.searchBST(cur.left)  # 遍历左子树
        # 中序遍历当前节点
        if self.pre is None:  # 如果是遍历的第一个节点
            self.count = 1
        elif self.pre.val == cur.val:  # 如果当前节点值与前一个节点值相同
            self.count += 1
        else:  # 如果当前节点值与前一个节点值不同
            self.count = 1
        self.pre = cur  # 更新上一个遍历的节点

        if self.count == self.maxCount:  # 如果当前元素的频率等于最大频率
            self.result.append(cur.val)  # 将当前元素添加到结果列表中

        if self.count > self.maxCount:  # 如果当前元素的频率大于最大频率
            self.maxCount = self.count  # 更新最大频率
            self.result = [cur.val]  # 清空结果列表,并将当前元素作为唯一元素添加进去

        self.searchBST(cur.right)  # 遍历右子树
        return

    def findMode(self, root):
        self.count = 0
        self.maxCount = 0
        self.pre = None  # 初始化上一个节点为空
        self.result = []  # 初始化结果列表为空

        self.searchBST(root)  # 开始中序遍历
        return self.result  # 返回出现频率最高的元素列表

讲解:

  1. 类的初始化

    • __init__ 方法初始化了一些变量:maxCount 用于记录BST中某个元素出现的最大频率,count 用于当前元素的频率计数,pre 用于记录上一个遍历的节点,result 用于存储出现频率最高的元素。
  2. 中序遍历搜索方法 searchBST

    • 这个方法对BST进行中序遍历(左-中-右顺序),以确保遍历的结果是一个递增序列。
    • if cur is None: return:如果当前节点为空,则直接返回。
    • self.searchBST(cur.left):首先递归遍历左子树。
    • 然后处理中间节点:
      • 如果 self.pre 为空,说明这是第一个遍历的节点,将 count 设为1。
      • 如果当前节点值等于前一个节点值,说明出现了相同的值,频率计数 count 增加1。
      • 如果当前节点值不等于前一个节点值,重置频率计数 count 为1。
      • 更新 self.pre 为当前节点。
    • 根据当前频率计数 count 和最大频率 maxCount 的关系,更新结果列表 result
      • 如果 count 等于 maxCount,将当前节点值添加到 result 列表中。
      • 如果 count 大于 maxCount,更新 maxCount 并重置 result 列表,仅包含当前节点值。
    • 最后递归遍历右子树 self.searchBST(cur.right)
  3. 寻找众数方法 findMode

    • 这个方法是寻找BST中的众数的入口方法。
    • 在调用中序遍历方法 searchBST 前,初始化所有变量。
    • 调用 searchBST 方法开始遍历BST。
    • 返回结果列表 result,其中包含了出现频率最高的元素。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值