LeetCode#501. 二叉搜索树中的众数

99 阅读1分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第16天,点击查看活动详情

一、题目描述:

501. 二叉搜索树中的众数

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

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

假定 BST 满足如下定义:

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

示例 1:

image.png

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

示例 2:

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

提示:

  • 树中节点的数目在范围 [1, 10^4] 内
  • -10^5 <= Node.val <= 10^5  

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

二、思路分析:

二分搜索树,先序遍历,一样的数是连续出现的,计数出现的数字,如果不一样就初始化为1,重新计算

如果不采用额外存储空间

  • 关键是采用哨兵模式,增加一个头节点,初始化的头节点状态是None,最大计数为0,当前计数默认为1,因为至少为1
  • 使用前节点(非空)的值和当前值比较,如果相同,计数加1;
  • 如果不同,比较当前计数与最大计数,更新最大计数,如果当前计数大于全局最大计数,列表重置为当前节点的值,如果相等,添加当前元素入列表;
  • 最后更新前置节点, 保证是和最近非空前置节点比较(中序遍历中的前置节点);

三、AC 代码:

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:

    def findMode(self, root: TreeNode) -> List[int]:

        self.prev_val = None 
        self.cur_cnt = 1

        self.nums = [] 
        self.max_cnt = 0

        self.help(root)
        return self.nums
    

    def help(self, root):
        if not root:
            return

        self.help( root.left )                
        if root.val == self.prev_val:
            self.cur_cnt += 1
        else:
            self.cur_cnt = 1
        if self.cur_cnt > self.max_cnt:
            self.nums = [root.val]
            self.max_cnt = self.cur_cnt
        elif self.cur_cnt == self.max_cnt:
            self.nums.append(root.val)                
        self.prev_val = root.val
            

        self.help(root.right)