对该题目描述是寻找二叉树中的众数,首先我们最直观的思路是遍历二叉树使用map统计各个结点值出现的频率,对该集合进行排序(或者遍历寻找出现次数最高的)。这对二叉树的遍历顺序就没有什么要求了,前中后序及层序遍历都是可以的,这是最先想到的,虽然思路不浮渣,但是这种实现代码量也确实不少。
我在这记录最优的解法,虽然也是学习别人的,但是不得不承认别人的思想很新颖。特此记录一下。
由于该题目是二叉搜索树,因此我们优先使用二叉树的中序遍历,因为二叉搜索树的中序遍历是有序的。
由此可以看出遍历顺序:1 2 3 4 5 6;
递归中序遍历代码结构
void searchBST(TreeNode cur) {
if (cur == NULL) return ;
searchBST(cur->left); // 左
(单层递归逻辑出代码) // 中
searchBST(cur->right); // 右
return ;
}
递归三部曲:
确定返回值和需要传入什么值
确定递归结束条件:如果递归中遇到栈溢出,就是递归条件没有选定好。
确定单层递归的逻辑。
双指针实现遍历二叉树寻找众数:定义两个指针cur,pre;分别表示当前结点,和当前结点的前一个结点。初始化是pre为NULL。
Java代码实现改题目:
class Solution {
//中序递归
List<Integer> list = new ArrayList<>();;
//当前结点cur的前一个结点
TreeNode pre = null;
//cur当前元素出现的次数
int count = 0;
//当前元素出现的最高频率
int maxCount = 0;
public int[] findMode(TreeNode root) {
//双指正遍历 寻找众数
findMode1(root);
//转化为int数组(防止众数有多个:如1 2 2 3 4 4 6)
//里面就有两个众数 2 和 4
int[] ints = new int[list.size()];
for (int i = 0; i < list.size(); i++) {
ints[i] = list.get(i);
}
return ints;
}
//中序遍历
public void findMode1(TreeNode cur) {
if (cur == null) return;
findMode1(cur.left);
//初始是pre为1,记录第一个元素出现的次数
if(pre == null) count =1;
//当cur与前一个的元素值相等时 count再加一
else if(pre.val== cur.val) count++;
//当pre不为空,说明cur的值与pre的值不等 说明cur指向了一个新的元素
//需要从新记录新元素出现的频率
else count = 1;
//当最高频率与元素的出现的频率相等的时候 把数据加入到容器中
if (count == maxCount){
list.add(cur.val);
}
//macCount初始值为0,count的值大于maxcount更新最高频率为count
if (count > maxCount) {
maxCount = count;
//出现评率发生了变化,容器中的数据需要全部清空
list.clear();
//再一次添加当前cur结点的值进入容器
list.add(cur.val);
}
//更新结点
pre = cur;
findMode1(cur.right);
return;
}
}
本来坚持每天写一道的,过年期间,经常醉酒坚持不下来,今天万往后,小涂回来啦!今天是正月十五元宵节,再次强调!
祝大家元宵节快乐!
祝大家元宵节快乐!
祝大家元宵节快乐!
看都到这里了,不管写的好啊不好给给小编点个赞吧,呵呵哈哈哈~~~~