LeetCode 501. Find Mode in Binary Search Tree - 二叉搜索树(Binary Search Tree)系列题11

本文介绍了一种在二叉搜索树中寻找出现频率最高数值的方法,通过两次中序遍历实现,无需额外空间。首次遍历统计各数值出现次数及最大计数,第二次遍历则将出现次数等于最大次数的数值加入结果。

Given the root of a binary search tree (BST) with duplicates, return all the mode(s) (i.e., the most frequently occurred element) in it.

If the tree has more than one mode, return them in any order.

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.

Example 1:

Input: root = [1,null,2,2]
Output: [2]

Example 2:

Input: root = [0]
Output: [0]

Constraints:

  • The number of nodes in the tree is in the range [1, 104].
  • -105 <= Node.val <= 105

Follow up: Could you do that without using any extra space? (Assume that the implicit stack space incurred due to recursion does not count).

题目给一个二叉搜索树(存在值相等的节点),要求找出出现次数最多的数值(可能存在多个数值)。

最简单的方法就是遍历整棵树,用一个hashmap记录所有数值出现的次数并算出最多次数,然后再遍历一遍hashmap找出所有出现次数最多的数值。这种解法没有用到二叉搜索树的特性而且空间复杂度是O(n),这也是这道题为什么被标注为easy的原因。

要做到空间复杂度是O(1),那就得用上二叉搜索树的特性。我们知道二叉搜索树中序遍历的序列是有序递增的,也就是说中序遍历的序列中所有相同数值是连续在一起的,所以在中序遍历过程中就可以同时统计每个数出现的次数。因此这道题可以通过两次中序遍历找到答案而不需要额外空间。

1)第一次遍历统计每个数出现的次数,中序遍历过程中维护一个当前节点的前继节点,一个计数变量和最大计数变量,当前节点值与前继节点值相等时表示出现相同数,计数变量加1;当前节点值与前继节点值不等时表示出现新的数字,重新开始计数;遍历过程实时更新最大计数变量。

2)第二次遍历用同样方法统计每个数出现的次数,由于这次已经知道最大次数,只要遇到次数等于最大次数的数就可以放入结果中。

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def findMode(self, root: Optional[TreeNode]) -> List[int]:
        res = []
        second = False
        cnt = 1
        maxCount = 1
        pre = None
        def inorder(cur):
            nonlocal pre, maxCount, cnt
            if not cur:
                return
            
            inorder(cur.left)
            if pre and cur.val == pre.val:
                cnt += 1
                if not second:
                    maxCount = max(maxCount, cnt)
            else:
                cnt = 1
            
            if second and cnt == maxCount:
                res.append(cur.val)
            pre = cur
            inorder(cur.right)
        
        inorder(root)
        second = True
        cnt = 1
        pre = None        
        inorder(root)
        
        return res

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值