# [501. Find Mode in Binary Search Tree](https://leetcode.com/problems/find-mode-in-binary-search-tree/) ###### tags: `Divide and Conquer`, `Binary Tree`, `Hash and Heap`, `Bloomberg` Description: Given the `root` of a binary search tree (BST) with duplicates, return *all the `mode(s)` (i.e., the most frequently occurred element) in it*. If the tree has more than one mode, return them in **any order**. Assume a BST is defined as follows: * The left subtree of a node contains only nodes with keys **less than or equal to** the node's key. * The right subtree of a node contains only nodes with keys **greater than or equal to** the node's key. * Both the left and right subtrees must also be binary search trees. ## Solution: * Naive: during traversing the tree, record the count of each node and compare out the max count. Then, get the nodes with max count. ```java= class Solution { public int[] findMode(TreeNode root) { Map<Integer, Integer> map = new HashMap<>(); int[] max = new int[1]; inorder(root, map, max); List<Integer> list = new ArrayList<>(); for (int key : map.keySet()) { int cnt = map.get(key); if (cnt == max[0]) list.add(key); } // good use of java.util.stream return list.stream().mapToInt(i -> i).toArray(); } private void inorder(TreeNode root, Map<Integer, Integer> map, int[] max) { if (root == null) return; inorder(root.left, map, max); map.put(root.val, map.getOrDefault(root.val, 0) + 1); max[0] = Math.max(max[0], map.get(root.val)); inorder(root.right, map, max); } } ``` Time: O(n) Space: O(n) * Tree Traversal (hard) ```java class Solution { private int[] modes; private Integer currVal; private int currCount = 0; private int modeCount = 0; private int maxCount = 0; public int[] findMode(TreeNode root) { inorder(root); modes = new int[modeCount]; modeCount = 0; currCount = 0; inorder(root); return modes; } private void inorder(TreeNode root) { if (root == null) return; inorder(root.left); helper(root.val); inorder(root.right); } private void helper(int val) { if (currVal == null) currVal = val; if (currVal != val) { currCount = 0; currVal = val; } currCount++; if (currCount > maxCount) { modeCount = 1; maxCount = currCount; } else if (currCount == maxCount) { if (modes != null && modeCount < modes.length) { modes[modeCount] = currVal; } modeCount++; } } } ``` Time: O(n) Space: O(1) * Tree Traversal (easy) ```java= class Solution { Integer prev; public int[] findMode(TreeNode root) { // cnt[0]: currCount // cnt[1]: maxCount int[] cnt = new int[2]; int[] prev = null; List<Integer> list = new ArrayList<>(); inorder(root, cnt, list); return list.stream().mapToInt(i -> i).toArray(); } private void inorder(TreeNode root, int[] cnt, List<Integer> list) { if (root == null) return; inorder(root.left, cnt, list); updateCount(root.val, cnt, list); inorder(root.right, cnt, list); } private void updateCount(int val, int[] cnt, List<Integer> list) { if (prev == null || prev != val) { cnt[0] = 0; prev = new Integer(val); } cnt[0]++; if (cnt[0] >= cnt[1]) { if (cnt[0] > cnt[1]) { cnt[1] = cnt[0]; list.clear(); } list.add(val); } } } ``` Time: O(n) Space: O(1) * Tree Traversal (Iterative) ```java= class Solution { public int[] findMode(TreeNode root) { if (root == null) { return new int[0]; } Stack<TreeNode> stack = new Stack(); while (root != null) { stack.push(root); root = root.left; } int prevVal = stack.peek().val; int maxCount = 0; int currCount = 0; List<Integer> list = new ArrayList<>(); while (!stack.isEmpty()) { TreeNode node = stack.pop(); if (node.val != prevVal) { currCount = 0; prevVal = node.val; } currCount++; if (currCount >= maxCount) { if (currCount > maxCount) { maxCount = currCount; list.clear(); } list.add(node.val); } node = node.right; while (node != null) { stack.push(node); node = node.left; } } return list.stream().mapToInt(i -> i).toArray(); } } ``` Time: O(n) Space: O(1)