精品推荐:
最近在网上看到一位清北的硕士被裁了,在大厂干了十多年,有名校光环再找工作应该不难,结果他说已经失业 4 个多月了,offer为 0 ,这应该是要求太高了,坑位太少了,降低要求肯定是能找到的。
网友评论:
--------------下面是今天的算法题--------------
来看下今天的算法题,这题是LeetCode的第501题:二叉搜索树中的众数。
问题描述
来源:LeetCode第501题
难度:简单
给你一个含重复值的二叉搜索树(BST)的根节点 root ,找出并返回 BST 中的所有 众数(即,出现频率最高的元素)。如果树中有不止一个众数,可以按任意顺序返回。
假定 BST 满足如下定义:
1,结点左子树中所含节点的值 小于等于 当前节点的值
2,结点右子树中所含节点的值 大于等于 当前节点的值
3,左子树和右子树都是二叉搜索树
示例1:
输入:root = [1,null,2,2]
输出:[2]
树中节点的数目在范围 [1, 10^4] 内
-10^5 <= Node.val <= 10^5
问题分析
这题让求的是二叉搜索树中的众数,如果求一个有序数组中的众数大家可能都会,但这里是一颗二叉搜索树。
我们知道二叉搜索树有一个重要的特性就是它的中序遍历结果一定是有序的,在有序数组中相同的元素一定是挨着的。
我们只需要对这棵树进行中序遍历,遍历的时候记录当前元素出现的次数,即可找到众数。注意这里的众数可能不止一个,所以找的时候,如果有多个数字出现的次数都一样,都要记录下来。
JAVA:
int maxCount = 0;// 出现的最高次数
int curVal = 0;// 当前值
int count = 0;// 当前值出现的次数
List<Integer> list = new ArrayList<>();
public int[] findMode(TreeNode root) {
dfs(root);
helper();// 最后一个元素要单独处理
return list.stream().mapToInt(x -> x).toArray();
}
private void dfs(TreeNode root) {
if (root == null) return;
dfs(root.left);// 递归左子树
if (root.val == curVal) {
count++;
} else {// 遇到新的值
helper();
// 更新新的值和它出现的频率
curVal = root.val;
count = 1;
}
dfs(root.right);// 递归右子树
}
private void helper() {
if (count > maxCount) {// 记录出现最高的次数
maxCount = count;
list.clear();// 之前出现次数少的清空
list.add(curVal);
} else if (count == maxCount) {
list.add(curVal);
}
}
C++:
public:
int maxCount = 0;// 出现的最高次数
int curVal = 0;// 当前值
int count = 0;// 当前值出现的次数
vector<int> vec;
vector<int> findMode(TreeNode *root) {
dfs(root);
helper();// 最后一个元素要单独处理
return vec;
}
void dfs(TreeNode *root) {
if (!root) return;
dfs(root->left);// 递归左子树
if (root->val == curVal) {
count++;
} else {// 遇到新的值
helper();
// 更新新的值和它出现的频率
curVal = root->val;
count = 1;
}
dfs(root->right);// 递归右子树
}
void helper() {
if (count > maxCount) {// 记录出现最高的次数
maxCount = count;
vec.clear();// 之前出现次数少的清空
vec.push_back(curVal);
} else if (count == maxCount) {
vec.push_back(curVal);
}
}
Python:
def findMode(self, root):
self.max_count = 0
self.cur_val = None
self.count = 0
self.list = []
self.dfs(root)
self.helper() # 最后一个元素要单独处理
return self.list
def dfs(self, root):
if not root:
return
self.dfs(root.left) # 递归左子树
if root.val == self.cur_val:
self.count += 1
else: # 遇到新的值
self.helper()
# 更新新的值和它出现的频率
self.cur_val = root.val
self.count = 1
self.dfs(root.right) # 递归右子树
def helper(self):
if self.count > self.max_count: # 记录出现最高的次数
self.max_count = self.count
self.list.clear() # 之前出现次数少的清空
self.list.append(self.cur_val)
elif self.count == self.max_count:
self.list.append(self.cur_val)
笔者简介
博哥,真名:王一博,毕业十多年,《算法秘籍》作者,专注于数据结构和算法的讲解,在全球30多个算法网站中累计做题2000多道,在公众号中写算法题解800多题,对算法题有自己独特的解题思路和解题技巧,喜欢的可以给个关注,也可以下载我整理的1000多页的PDF算法文档。