[Leetcode]42.二叉搜索树中的众数
题目:给定一个有相同值的二叉搜索树(BST),找出 BST 中的所有众数(出现频率最高的元素)。
假定 BST 有如下定义:
- 结点左子树中所含结点的值小于等于当前结点的值
- 结点右子树中所含结点的值大于等于当前结点的值
- 左子树和右子树都是二叉搜索树
例如:
给定 BST [1,null,2,2],
1
\
2
/
2
返回[2].
思想:遍历这棵二叉搜索树,观察到重复的元素都是相邻的,设置一个计数器用于计数重复最多的元素出现的次数,一个数组用于保存出现最多的元素,如果出现大于当前重复次数的元素,将数组清空放入新的元素。
其中遍历方法可以采用中序遍历递归的方法,也可以使用morris来优化这个过程。
其中morris遍历的主要思想如下:
记当前节点为cur。
- 如果cur无左孩子,cur向右移动(cur=cur.right)
- 如果cur有左孩子,找到cur左子树上最右的节点,记为mostright
- 如果mostright的right指针指向空,让其指向cur,cur向左移动(cur=cur.left)
- 如果mostright的right指针指向cur,让其指向空,cur向右移动(cur=cur.right)
实现以上的原则,即实现了morris遍历。
这种方法可以使得遍历的过程不需要额外记录和递归的过程。
递归中序遍历方法:
func findMode(root *TreeNode) []int {
var res []int
var repeat int = 0
var maxrepeat int = 0
var cur int
update := func(x int){
if x == cur{
repeat++
}else{
cur , repeat = x,1
}
if repeat == maxrepeat{
res = append(res,cur)
}else if repeat> maxrepeat{
maxrepeat = repeat
res = []int{cur}
}
}
var dfs func(root *TreeNode)
dfs = func(root *TreeNode) {
if root==nil{
return
}else{
dfs(root.Left)
update(root.Val)
dfs(root.Right)
}
}
dfs(root)
return res
}
morris优化方法:
func findMode(root *TreeNode) []int {
var res []int
var repeat int = 0
var maxrepeat int = 0
var cur int
var curnode = root
update := func(x int){
if x == cur{
repeat++
}else{
cur , repeat = x,1
}
if repeat == maxrepeat{
res = append(res,cur)
}else if repeat> maxrepeat{
res = []int{cur}
}
}
for curnode!=nil{
if curnode.Left==nil{
update(curnode.Val)
curnode = curnode.Right
continue
}
pre := curnode.Left
for pre.Right!=nil&&pre.Right!=curnode{
pre = pre.Right
}
if pre.Right ==nil{
pre.Right = curnode
curnode=curnode.Left
}else{
pre.Right = nil
update(curnode.Val)
curnode =curnode.Right
}
}
return res
}
题目来源:https://leetcode-cn.com/problems/find-mode-in-binary-search-tree/submissions/

浙公网安备 33010602011771号