leetcode 501: 二叉搜索树中的众数

leetcode 501:二叉搜索树中的众数

题目描述

给定一个有相同值的二叉搜索树(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

运行结果:
501解法1
解法二:利用二叉搜索树的性质,二叉搜索树在中序遍历(左根右)后,会得到一个从小到大排列的序列。在中序遍历中,将当前值与前一个值比较,如果相同,则当前次数加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

运行结果:
5012
与解法一相比,时间并没有提升,因为两个方法都遍历了整个二叉树。但是在空间复杂度上,解法二应该是优于解法一的,因为解法二没有使用额外的空间,解法一的额外空间就是那个存储值与次数的字典,解法二就是只用了一个res存储结果。不过最坏情况下,两个解法的空间复杂度都是O(n).
PS. 中序遍历可用递归写法

本周第二篇博客完成,撒花!
老师到底什么时候公布寒假时间哦,我真的很难抢票啊!!
12点35了,该睡觉了,头发要保护好

发布了28 篇原创文章 · 获赞 11 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/xxx_gt/article/details/103606006
今日推荐