Bootstrap

代码随想录二叉树——二叉搜索树中的众数

题目

给定一个有相同值的二叉搜索树(BST),找出 BST 中的所有众数(出现频率最高的元素)。

假定 BST 有如下定义:

结点左子树中所含结点的值小于等于当前结点的值
结点右子树中所含结点的值大于等于当前结点的值
左子树和右子树都是二叉搜索树
例如:

给定 BST [1,null,2,2],
在这里插入图片描述

返回[2].

提示:如果众数超过1个,不需考虑输出顺序

进阶:你可以不使用额外的空间吗?(假设由递归产生的隐式调用栈的开销不被计算在内)

思路

二叉搜索树—>中序遍历有序

遍历有序数组的元素出现频率,从头遍历一定是相邻两个元素两两对比,然后把频率最高的元素输出就可以了。(可以使用双指针法,pre指向前一个节点,cur指向当前节点)

找众数(最大频率的元素集合)有两种方法:

  1. 两次遍历:先遍历一遍数组,找出最大频率,然后再遍历一遍数组把出现频率为maxCount的元素放进集合中(因为众数可以有多个,所以是集合)
  2. 一次遍历直接初始化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;
}
;