携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第16天,点击查看活动详情
一、题目描述:
给你一个含重复值的二叉搜索树(BST)的根节点 root ,找出并返回 BST 中的所有 众数(即,出现频率最高的元素)。
如果树中有不止一个众数,可以按 任意顺序 返回。
假定 BST 满足如下定义:
- 结点左子树中所含节点的值 小于等于 当前节点的值
- 结点右子树中所含节点的值 大于等于 当前节点的值
- 左子树和右子树都是二叉搜索树
示例 1:
输入: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)