题目描述
给定一个有相同值的二叉搜索树(BST),找出 BST 中的所有众数(出现频率最高的元素)。
假定 BST 有如下定义:
结点左子树中所含结点的值小于等于当前结点的值
结点右子树中所含结点的值大于等于当前结点的值
左子树和右子树都是二叉搜索树
Given a binary search tree (BST) with duplicates, find all the mode(s) (the most frequently occurred element) in the given BST.
Assume a BST is defined as follows:
The left subtree of a node contains only nodes with keys less than or equal to the node’s key.
The right subtree of a node contains only nodes with keys greater than or equal to the node’s key.
Both the left and right subtrees must also be binary search trees.
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/find-mode-in-binary-search-tree
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
我的解法
解法一:二叉树先序遍历+字典存储值与出现的次数
其实和508题很类似,但是这个解法没有利用到这是个二叉搜索树的性质。任意一个二叉树都可以这么解。
代码如下:
from collections import defaultdict
class Solution:
def findMode(self, root: TreeNode) -> List[int]:
if not root:
return []
res = defaultdict(int)
stack = [root]
while stack:
root = stack.pop()
res[root.val] += 1
if root.right: stack.append(root.right)
if root.left: stack.append(root.left)
t = []
for k in sorted(res,key=res.__getitem__,reverse=True):
if t :
if res[k] == res[t[-1]]:
t.append(k)
else:
break
else:
t.append(k)
return t
运行结果:
解法二:利用二叉搜索树的性质,二叉搜索树在中序遍历(左根右)后,会得到一个从小到大排列的序列。在中序遍历中,将当前值与前一个值比较,如果相同,则当前次数加1,当前次数与最大次数比较。如果不同,则当前次数置为1,更新前一个值。
class Solution:
def findMode(self, root: TreeNode) -> List[int]:
if not root:
return []
res = []
times = 1
# 中序遍历
stack = []
cur = root
curtimes = 1
pre = float('inf')
while stack or cur:
while cur:
stack.append(cur)
cur = cur.left
cur = stack.pop()
# res.append(cur.val)
if cur.val == pre:
curtimes += 1
else:
curtimes = 1
pre = cur.val
if curtimes == times:
res.append(cur.val)
if curtimes > times:
res = [cur.val]
times = curtimes
cur = cur.right
return res
运行结果:
与解法一相比,时间并没有提升,因为两个方法都遍历了整个二叉树。但是在空间复杂度上,解法二应该是优于解法一的,因为解法二没有使用额外的空间,解法一的额外空间就是那个存储值与次数的字典,解法二就是只用了一个res存储结果。不过最坏情况下,两个解法的空间复杂度都是O(n).
PS. 中序遍历可用递归写法
本周第二篇博客完成,撒花!
老师到底什么时候公布寒假时间哦,我真的很难抢票啊!!
12点35了,该睡觉了,头发要保护好