二叉搜索树中的众数
来源:https://leetcode-cn.com/problems/find-mode-in-binary-search-tree
给定一个有相同值的二叉搜索树(BST),找出 BST 中的所有众数(出现频率最高的元素)。
假定 BST 有如下定义:
结点左子树中所含结点的值小于等于当前结点的值
结点右子树中所含结点的值大于等于当前结点的值
左子树和右子树都是二叉搜索树
例如:
给定 BST [1,null,2,2],
返回[2]
.
提示:如果众数超过1个,不需考虑输出顺序
进阶:你可以不使用额外的空间吗?(假设由递归产生的隐式调用栈的开销不被计算在内)
题解:简单的思路是hash解法,根据数值绝对值取模,每次插入查一下存不存在,存在直接加,不存在插入hash节点,这样解需要额外的空间。
那么如何不使用额外的空间?
解法一(hash):
public class 二叉搜索树中的众数501 { private long[] head = new long[100010]; private long[] next = new long[100010]; private long[] hash = new long[100010]; private long[] num = new long[100010]; private long max = -Long.MAX_VALUE; private List<Long> vals = new ArrayList<>(); int MOD = 100010; int top = 1; private int find(long x){ for (long i = head[(int)((x<0?-x:x) % MOD)]; i != 0; i = next[(int)i]){ if(x == hash[(int)i]){ return (int)i; } } return -1; } private void add(long x){ int index = find(x); if(index > 0){ findMax(index, x); return; } int i = (int)((x<0?-x:x) % MOD); hash[top] = x; next[top] = head[i]; head[i] = top; findMax(top, x); top++; } private void findMax(int top, long x) { num[top]++; if(num[top] > max){ vals.clear(); vals.add(x); max = num[top]; }else if(num[top] == max){ vals.add(x); } } public void dfs(TreeNode root) { if(root == null){ return; } add(root.val); dfs(root.left); dfs(root.right); } public int[] findMode(TreeNode root) { dfs(root); int[] answers = new int[vals.size()]; for(int i = 0; i < vals.size(); i++){ answers[i] = vals.get(i).intValue(); } return answers; } public static void main(String[] args) { 二叉搜索树中的众数501 二叉搜索树中的众数501 = new 二叉搜索树中的众数501(); 二叉搜索树中的众数501.add(1L); 二叉搜索树中的众数501.add(1L); } }
解法二:因为该数左孩子一定小于等于根节点,右树一定大于等于根节点,那么中序遍历肯定是有序数列,那么中序遍历时判断连续相等的最大节点数即可
public class 二叉搜索树中的众数501 { int maxNum, count; long last; Set<Long> maxVal = new HashSet<>(); public void dfs(TreeNode root){ if(root == null){ return; } dfs(root.left); findMax(root.val); last = root.val; dfs(root.right); } private void findMax(long val) { if (maxNum == 0 || val == last){ count++; }else { count = 1; } if(count > maxNum){ maxNum = count; maxVal.clear(); maxVal.add(val); }else if(count == maxNum){ maxVal.add(val); } } public int[] findMode(TreeNode root) { dfs(root); int[] answers = new int[maxVal.size()]; int i = 0; for(Long val : maxVal){ answers[i++] = val.intValue(); } return answers; } public static void main(String[] args) { 二叉搜索树中的众数501 二叉搜索树中的众数501 = new 二叉搜索树中的众数501(); InputUtils.buildMiddle(); 二叉搜索树中的众数501.findMode(InputUtils.head); } }