Easy
题目描述
给你一个含重复值的二叉搜索树(BST)的根节点 root,找出并返回 BST 中的所有众数(即,出现频率最高的元素)。
如果树中有不止一个众数,可以按 任意顺序 返回。
假定 BST 满足如下定义:
- 结点左子树中所含节点的值 小于等于 当前节点的值
- 结点右子树中所含节点的值 大于等于 当前节点的值
- 左子树和右子树都是二叉搜索树
示例 1:
输入:root = [1,null,2,2]
输出:[2]
示例 2:
输入:root = [0]
输出:[0]
提示:
- 树中节点数的范围在
[1, 10^4]内 -10^5 <= Node.val <= 10^5
进阶: 你可以不使用额外的空间吗?(假设由递归产生的隐式调用栈的开销不被计算在内)
解题思路
这道题有两种主要思路:
方法一:哈希表统计(简单直观) 使用哈希表统计每个值的出现频率,然后找出最大频率对应的所有值。这种方法简单易懂,但需要额外的存储空间。
方法二:中序遍历(推荐解法) 利用BST的性质,中序遍历可以得到有序序列。在遍历过程中维护当前值、当前频率、最大频率等信息,一次遍历即可找到所有众数。这种方法更高效,空间复杂度更优。
具体实现时,我们维护以下变量:
prev:上一个遍历的值count:当前值的频率maxCount:最大频率result:结果数组
当遍历到新值时,重置计数;当频率等于最大频率时,加入结果;当频率大于最大频率时,更新最大频率并重置结果数组。
代码实现
class Solution {
public:
vector<int> findMode(TreeNode* root) {
vector<int> result;
int prev = INT_MIN, count = 0, maxCount = 0;
function<void(TreeNode*)> inorder = [&](TreeNode* node) {
if (!node) return;
inorder(node->left);
if (prev == node->val) {
count++;
} else {
count = 1;
prev = node->val;
}
if (count > maxCount) {
maxCount = count;
result.clear();
result.push_back(node->val);
} else if (count == maxCount) {
result.push_back(node->val);
}
inorder(node->right);
};
inorder(root);
return result;
}
};
class Solution:
def findMode(self, root: Optional[TreeNode]) -> List[int]:
def inorder(node):
if not node:
return
inorder(node.left)
if self.prev == node.val:
self.count += 1
else:
self.count = 1
self.prev = node.val
if self.count > self.max_count:
self.max_count = self.count
self.result = [node.val]
elif self.count == self.max_count:
self.result.append(node.val)
inorder(node.right)
self.prev = None
self.count = 0
self.max_count = 0
self.result = []
inorder(root)
return self.result
public class Solution {
private List<int> result = new List<int>();
private int prev = int.MinValue;
private int count = 0;
private int maxCount = 0;
public int[] FindMode(TreeNode root) {
Inorder(root);
return result.ToArray();
}
private void Inorder(TreeNode node) {
if (node == null) return;
Inorder(node.left);
if (prev == node.val) {
count++;
} else {
count = 1;
prev = node.val;
}
if (count > maxCount) {
maxCount = count;
result.Clear();
result.Add(node.val);
} else if (count == maxCount) {
result.Add(node.val);
}
Inorder(node.right);
}
}
var findMode = function(root) {
let modes = [];
let maxCount = 0;
let currentCount = 0;
let prevVal = null;
function inorder(node) {
if (!node) return;
inorder(node.left);
if (prevVal === node.val) {
currentCount++;
} else {
currentCount = 1;
prevVal = node.val;
}
if (currentCount > maxCount) {
maxCount = currentCount;
modes = [node.val];
} else if (currentCount === maxCount) {
modes.push(node.val);
}
inorder(node.right);
}
inorder(root);
return modes;
};
复杂度分析
| 复杂度 | 大小 | 说明 |
|---|---|---|
| 时间复杂度 | O(n) | n为节点数,需要遍历所有节点一次 |
| 空间复杂度 | O(h) | h为树的高度,递归调用栈的深度 |
相关题目
- . Validate Binary Search Tree (Medium)