题目:
给你一个含重复值的二叉搜索树(BST)的根节点 root
,找出并返回 BST 中的所有 众数(即,出现频率最高的元素)。
如果树中有不止一个众数,可以按 任意顺序 返回。
假定 BST 满足如下定义:
- 结点左子树中所含节点的值 小于等于 当前节点的值
- 结点右子树中所含节点的值 大于等于 当前节点的值
- 左子树和右子树都是二叉搜索树
思路:中序遍历二叉搜索树可以得到递增序列。
用pre存储前一个便利的节点,root为现在访问的节点 ,count存储现在访问的节点值出现的频率,maxCount存储节点值中最大出现频率,resList存储结果集。
如果pre=null或root.val!=pre.val说明root节点值未出现过,令count=1;否则root节点值以及出现过,count+1。
然后判断count与maxCount的关系。如果count>maxCount,说明resList结果集中存储的结果全都不符合要求,需要清除,把root.val加入结果集,maxCount需要更新为count;如果count=maxCount,则把root.val加入结果集;如果count<maxCount,不需要任何处理。
递归代码:
List<Integer> resList=new ArrayList<>();//结果集int maxcount=0;//记录最大频率int count=0;//记录当前节点值出现的频率TreeNode pre=null;//记录前一个遍历节点public int[] findMode(TreeNode root) {find(root);return resList.stream().mapToInt(Integer::intValue).toArray();}public void find(TreeNode root){if(root==null) return;find(root.left);//计数if(pre==null||root.val!=pre.val)count=1;elsecount++;//更新结果以及maxcountif(count>maxcount){resList.clear();//最大频率次数改变,之前统计的结果需要全部清除resList.add(root.val);maxcount=count;}else if(count==maxcount){resList.add(root.val);}pre=root;find(root.right);}
注意:返回值为int数组,结果集为List,将List转换为int数组不能直接调用toArray()函数,因为toArray()的返回值为Object数组。借助stream流,将List存储到stream流中在转换为int数组。
迭代代码:
public int[] findMode(TreeNode root) {List<Integer> resList=new ArrayList<>();//结果集int maxcount=0;//记录最大频率int count=0;//记录当前节点值出现的频率TreeNode pre=null;//记录前一个遍历节点Stack<TreeNode> stack=new Stack<>();if(root!=null)stack.add(root);while(!stack.isEmpty()){TreeNode cur=stack.peek();if(cur!=null){stack.pop();if(cur.right!=null) stack.add(cur.right);stack.add(cur);stack.add(null);if(cur.left!=null) stack.add(cur.left);}else{stack.pop();TreeNode tmp=stack.pop();//计数if(pre==null||tmp.val!=pre.val)count=1;else count++;pre=tmp;//更新pre//更新maxcount与resListif(count>maxcount){resList.clear();maxcount=count;resList.add(tmp.val);}else if(count==maxcount){resList.add(tmp.val);}}}return resList.stream().mapToInt(Integer::intValue).toArray();}