题目
给定一个有相同值的二叉搜索树(BST),找出 BST 中的所有众数(出现频率最高的元素)。
假定 BST 有如下定义:
结点左子树中所含结点的值小于等于当前结点的值
结点右子树中所含结点的值大于等于当前结点的值
左子树和右子树都是二叉搜索树
例如:
给定 BST [1,null,2,2],
返回[2].
提示:如果众数超过1个,不需考虑输出顺序
进阶:你可以不使用额外的空间吗?(假设由递归产生的隐式调用栈的开销不被计算在内)
思路
二叉搜索树—>中序遍历有序
遍历有序数组的元素出现频率,从头遍历一定是相邻两个元素两两对比,然后把频率最高的元素输出就可以了。(可以使用双指针法,pre指向前一个节点,cur指向当前节点)
找众数(最大频率的元素集合)有两种方法:
- 两次遍历:先遍历一遍数组,找出最大频率,然后再遍历一遍数组把出现频率为maxCount的元素放进集合中(因为众数可以有多个,所以是集合)
- 一次遍历:直接初始化maxCount,如果count=maxCount,那么把这个元素加入集合中,如果新统计的count > maxCount,那么不仅更新maxCount,而且清空结果集。
//递归法,采用一次遍历找众数,中序遍历
class Solution {
ArrayList<Integer> resList;
int maxCount;
int count;
TreeNode pre;
public int[] findMode(TreeNode root){
resList = new ArrayList<>();//初始化集合
maxCount = 0;
count = 0;
pre = null;
findMode1(root);//从根节点开始,找出众数集合resList
int[] res = new int[resList.size()];//将集合存储到数组中去,进行遍历
for(int i = 0;i < resList.size(); i++){
res[i] = resList.get(i);
}
return res;//返回有序数组
}
public void findMode1(TreeNode root){
if(root == null){
return;
}
findMode1(root.left);//左,为中序遍历代码模板
int rootValue = root.val;//记录根节点的值
//计数
if(pre == null || rootValue != pre.val){//如果前驱节点为空即第一个节点,或者当前节点的值不等于上一个节点即相邻两个元素不相等
count = 1;//频率为1
}else {//当前节点与前一个节点元素值相等
count++;//频率+1
}
//更新结果以及maxCount
if(count > maxCount){
resList.clear();
resList.add(rootValue);
maxCount = count;//更新最大频率
}
else if(count == maxCount){
resList.add(rootValue);
}
pre = root;//指针后移
findMode1(root.right);//右,为中序遍历代码模板
}
}
//中序遍历代码模板
void searchBST(TreeNode root){
if(root == null){
return;
}
searchBST();//左
(处理节点的操作)//中
searchBST();//右
return;
}