二叉搜索树中的众数

LeetCode每日一题,501 Find Mode In Binary Search Tree

先看题目描述

大意就是给定一棵二叉搜索树,让我们返回其中出现次数最多的数

算法思路

这题如果不管 follow up 的话就很简单,只需要用一个列表记录下这棵二叉搜索树的中根遍历序列,然后遍历这个列表,找出其中出现次数最多的树即可。但是如果要做 follow up 的话,即除了栈不用其他额外空间,那么的话难度就大些,我们需要在中根遍历一遍以后就得到在二叉搜索树中出现次数最多的树

递归

  • 递归的对这棵二叉搜索树进行中根遍历
  • 在遍历的过程中维护四个信息
    1. 存储出现次数最多的数的列表 res
    2. 当前所有数字中出现的最多次数 max
    3. 上一个节点的值 preVal
    4. 目前数字连续出现的次数 len
  • 每当遍历到一个节点时
    • 若 当前节点的值与 preVal 相等,则将 len + 1
    • 若当前节点的值与 preVal 不相等,则将 len 与 max 进行比较
      • 若 len 与 max 相等,则在 res 末尾添加 preVal
      • 若 len > max,则将 res 清空,并将 preVal 添加到 res 中,置 max = len
      • 置 preVal = 当前节点的值,len = 1
  • 遍历完所有节点后,因为此时最后的连续相等节点还未考虑,在最后还需进行一步操作,将 len 与 max 进行比较
    • 若 len 与 max 相等,则在 res 末尾添加 preVal
    • 若 len > max,则将 res 清空,并将 preVal 添加到 res 中
  • 将 res 转化为数组,将结果返回

算法源码

递归

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
import java.util.*;

/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
List<Integer> res = new ArrayList<>();
private int max = 1;
private int preVal = 0;
private int len = 0;

public int[] findMode(TreeNode root) {
dfs(root);
if (len == max) res.add(preVal);
if (len > max) {
res.clear();
res.add(preVal);
}
int[] ans = new int[res.size()];
for (int i = 0; i < res.size(); i++) {
ans[i] = res.get(i);
}
return ans;
}

private void dfs(TreeNode root) {
if (root == null) return;
dfs(root.left);
if (root.val != preVal) {
if (len == max) res.add(preVal);
if (len > max) {
res.clear();
res.add(preVal);
max = len;
}
preVal = root.val;
len = 1;
} else {
len++;
}
dfs(root.right);
}
}

这个实际上就是将递归实现中根遍历的过程手动用栈模拟了出来,但不知为什么效率不如直接使用递归的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
import java.util.*;

/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public int[] findMode(TreeNode root) {
if (root == null) return new int[0];
List<Integer> res = new ArrayList<>();
int max = 1;
LinkedList<TreeNode> stack = new LinkedList<TreeNode>();
int preVal = 0;
int len = 0;
while (root != null || !stack.isEmpty()) {
while (root != null) {
stack.add(root);
root = root.left;
}
root = stack.removeLast();
if (root.val == preVal) {
len += 1;
} else{
if (len == max) res.add(preVal);
if (len > max) {
max = len;
res.clear();
res.add(preVal);
}
len = 1;
preVal = root.val;
}
root = root.right;
}
if (len == max) res.add(preVal);
if (len > max) {
res.clear();
res.add(preVal);
}
int[] ans = new int[res.size()];
for (int i = 0; i < res.size(); i++) {
ans[i] = res.get(i);
}
return ans;
}
}