给定一个有相同值的二叉搜索树(BST),找出 BST 中的所有众数(出现频率最高的元素)。
假定 BST 有如下定义:
结点左子树中所含结点的值小于等于当前结点的值
结点右子树中所含结点的值大于等于当前结点的值
左子树和右子树都是二叉搜索树
例如:
给定 BST [1,null,2,2],
返回[2].
提示:如果众数超过1个,不需考虑输出顺序
进阶:你可以不使用额外的空间吗?(假设由递归产生的隐式调用栈的开销不被计算在内)
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/find-mode-in-binary-search-tree
python
# 0501.二叉搜索树中的众数
# 递归-数组-map->找众数
class Solution:
def __init__(self):
pass
def findMode(self, root:TreeNode) -> [int]:
bstList = []
def travel(root):
nonlocal bstList
if not root:
return
travel(root.left)
bstList.append(root.val)
travel(root.right)
travel(root)
from collections import defaultdict
mapFre = defaultdict(int)
for i in bstList:
mapFre[i] += 1
result = []
Max = 0
for k,v in mapFre.items():
if Max < v:
Max = v
for k,v in mapFre.items():
if v == Max:
result.append(k)
return result
# 递归-数组-找众数
class Solution1:
def __init__(self):
self.maxCnt = 0
self.pre = None
self.res = []
self.cnt = 0
def findMode(self, root: TreeNode) -> [int]:
def inorder(node):
if not node:
return
inorder(node.left)
if self.pre == None:
self.cnt = 1
elif self.pre.val == node.val:
self.cnt += 1
else:
self.cnt = 1
self.pre = node
if self.cnt == self.maxCnt:
self.res.append(node.val)
if self.cnt > self.maxCnt:
self.maxCnt = self.cnt
self.res.clear()
self.res.append(node.val)
inorder(node.right)
if not root: return []
inorder(root)
return self.res
golang
package binaryTree
// 递归-数组-map-> 找众数
func findMode(root *TreeNode) []int {
var bstArr = []int{}
var traversal func(node *TreeNode)
traversal = func(node *TreeNode) {
if node == nil {
return
}
traversal(node.Left)
bstArr = append(bstArr, node.Val)
traversal(node.Right)
}
traversal(root)
mapFre := map[int]int{}
for v := range bstArr {
mapFre[v] += 1
}
res := []int{}
Max := 0
for _,v := range mapFre {
if Max < v {
Max = v
}
}
for k, v := range mapFre {
if v == Max {
res = append(res, k)
}
}
return res
}
// 递归-有限变量
func findMode1(root *TreeNode) []int {
maxCnt := 0 // 最大频次
cnt := 0 // 当前元素的出现频次
var pre *TreeNode // 前驱节点
res := []int{} // 保存众数
var dfsInorder func(root *TreeNode) // 中序遍历
dfsInorder = func(root *TreeNode) {
if root == nil {
return
}
dfsInorder(root.Left)
if pre != nil && pre.Val == root.Val {
cnt++ // 同前驱, cnt++
} else {
cnt = 1 // 首次出现,非重元素,频次初始化
}
if cnt == maxCnt {
res = append(res, root.Val) // 放入res
}
if cnt > maxCnt { // 遇到频次更大的元素
res = []int{} // 清空res
maxCnt = cnt
res = append(res, root.Val) // 放入众数
}
pre = root // 更新前驱
dfsInorder(root.Right)
}
dfsInorder(root)
return res
}