LeetCode(Binary Search Tree)501. Find Mode in Binary Search Tree

绝地灬酷狼 2023-09-26 20:39 135阅读 0赞

1.问题

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.

Example 1:
在这里插入图片描述

Input: root = [1,null,2,2]
Output: [2]

Example 2:

Input: root = [0]
Output: [0]

Constraints:

  • The number of nodes in the tree is in the range [1, 104].
  • -105 <= Node.val <= 105

Follow up: Could you do that without using any extra space? (Assume that the implicit stack space incurred due to recursion does not count).

2. 解题思路

方法1:

1.定义一个哈希表用于存储每个节点的值和出现次数,以及一个变量记录出现次数最多的节点出现次数。
2.对二叉树进行中序遍历,对于每个节点,将其节点值在哈希表中对应的出现次数加1,并更新最大出现次数。
3.遍历哈希表,将出现次数等于最大出现次数的节点值添加到一个列表中。
4.将列表转换成数组形式作为结果返回。

方法2:

  1. 基于中序遍历实现的。
  2. 在遍历过程中,维护三个变量:prev、count和maxCount。
  3. prev表示上一个遍历的节点的值。
  4. count表示当前节点的值在当前遍历路径上的出现次数。
  5. maxCount表示当前路径上任何一个节点的出现次数的最大值。
  6. 在遍历到当前节点时,如果当前节点值等于上一个节点值,则将count加1,否则将count重置为1。
  7. 然后,如果count的值大于maxCount,则将maxCount更新为count,并且将result清空,将当前节点值添加到result中;如果count等于maxCount,则将当前节点值添加到result中。
  8. 最后,将result转换成数组返回即可。

3. 代码

代码1:

  1. /**
  2. * Definition for a binary tree node.
  3. * public class TreeNode {
  4. * int val;
  5. * TreeNode left;
  6. * TreeNode right;
  7. * TreeNode() {}
  8. * TreeNode(int val) { this.val = val; }
  9. * TreeNode(int val, TreeNode left, TreeNode right) {
  10. * this.val = val;
  11. * this.left = left;
  12. * this.right = right;
  13. * }
  14. * }
  15. */
  16. class Solution {
  17. Map<Integer, Integer> map = new HashMap<>(); // 哈希表用于存储节点值和出现次数
  18. int maxCount = 0; // 记录出现次数最多的节点出现次数
  19. public int[] findMode(TreeNode root) {
  20. inOrder(root); // 中序遍历二叉树,统计每个节点出现次数
  21. List<Integer> list = new ArrayList<>();
  22. for (int key : map.keySet()) {
  23. // 遍历哈希表
  24. if (map.get(key) == maxCount) {
  25. // 如果该节点出现次数等于最大出现次数
  26. list.add(key); // 添加到列表中
  27. }
  28. }
  29. int[] res = new int[list.size()]; // 创建结果数组
  30. for (int i = 0; i < res.length; i++) {
  31. // 遍历列表,将结果转换成数组形式
  32. res[i] = list.get(i);
  33. }
  34. return res;
  35. }
  36. private void inOrder(TreeNode node) {
  37. // 中序遍历二叉树,统计每个节点出现次数
  38. if (node == null) {
  39. return;
  40. }
  41. inOrder(node.left);
  42. int count = map.getOrDefault(node.val, 0) + 1; // 获取节点值在哈希表中的出现次数并加1
  43. map.put(node.val, count); // 更新哈希表中节点值的出现次数
  44. maxCount = Math.max(maxCount, count); // 更新最大出现次数
  45. inOrder(node.right);
  46. }
  47. }

代码2:

  1. class Solution {
  2. private int prev = -1;
  3. private int count = 1;
  4. private int maxCount = 0;
  5. private List<Integer> result = new ArrayList<>();
  6. public int[] findMode(TreeNode root) {
  7. inorder(root);
  8. int[] res = new int[result.size()];
  9. for (int i = 0; i < result.size(); i++) {
  10. res[i] = result.get(i);
  11. }
  12. return res;
  13. }
  14. private void inorder(TreeNode root) {
  15. if (root == null) {
  16. return;
  17. }
  18. inorder(root.left);
  19. if (prev != -1) {
  20. if (root.val == prev) {
  21. count++;
  22. } else {
  23. count = 1;
  24. }
  25. }
  26. if (count > maxCount) {
  27. maxCount = count;
  28. result.clear();
  29. result.add(root.val);
  30. } else if (count == maxCount) {
  31. result.add(root.val);
  32. }
  33. prev = root.val;
  34. inorder(root.right);
  35. }
  36. }

和代码2的思路基本相同
相同:使用中序遍历二叉搜索树,统计每个数字出现的次数,根据出现次数更新结果集和最大出现次数。
不同:使用了 List 来存储结果集,而之前的代码使用了 int[],另外,这段代码在遍历每个数字时,使用 pre 变量记录当前数字的前一个数字,而之前的代码则是在递归中传入参数。

  1. class Solution {
  2. // 定义结果集
  3. List<Integer> list = new ArrayList<>();
  4. // 当前数字出现的次数和出现次数最多的数字的出现次数
  5. int curCount = 0, maxCount = 0;
  6. // 用于记录当前数字的前一个数字
  7. Integer pre = null;
  8. public int[] findMode(TreeNode root) {
  9. // 中序遍历
  10. inorder(root);
  11. int[] res = new int[list.size()];
  12. for (int i = 0; i < list.size(); i++) {
  13. res[i] = list.get(i);
  14. }
  15. return res;
  16. }
  17. private void inorder(TreeNode root) {
  18. if (root == null) {
  19. return;
  20. }
  21. // 遍历左子树
  22. inorder(root.left);
  23. // 统计当前数字出现的次数
  24. if (pre != null && pre == root.val) {
  25. curCount++;
  26. } else {
  27. curCount = 1;
  28. }
  29. // 根据出现次数更新结果集和maxCount
  30. if (curCount == maxCount) {
  31. list.add(root.val);
  32. } else if (curCount > maxCount) {
  33. list.clear();
  34. list.add(root.val);
  35. maxCount = curCount;
  36. }
  37. // 更新pre
  38. pre = root.val;
  39. // 遍历右子树
  40. inorder(root.right);
  41. }
  42. }

发表评论

表情:
评论列表 (有 0 条评论,135人围观)

还没有评论,来说两句吧...

相关阅读