每日一练:LeeCode-501、二叉搜索树中的众数【二叉搜索树+pre辅助节点+DFS】

本文是力扣LeeCode-LeeCode-501、二叉搜索树中的众数【二叉搜索树+pre辅助节点+DFS】 学习与理解过程,本文仅做学习之用,对本题感兴趣的小伙伴可以出门左拐LeeCode。

给你一个含重复值的二叉搜索树(BST)的根节点 root ,找出并返回 BST 中的所有 众数(即,出现频率最高的元素)。

如果树中有不止一个众数,可以按 任意顺序 返回

假定 BST 满足如下定义:

  • 结点左子树中所含节点的值 小于等于 当前节点的值
  • 结点右子树中所含节点的值 大于等于 当前节点的值
  • 左子树和右子树都是二叉搜索树

示例 1:
每日一练:LeeCode-501、二叉搜索树中的众数【二叉搜索树+pre辅助节点+DFS】_第1张图片

输入:root = [1,null,2,2]
输出:[2]

示例 2:

输入:root = [0]
输出:[0]

提示:

  • 树中节点的数目在范围 [1, 104] 内
  • -10^5 <= Node.val <= 10^5

思路

思路一(普通二叉树)

首先这道题要求的是二叉搜索树,如果为我们直接把它当成一颗普通⼆叉树,也是可以直接解决的遍历存数组+使用map统计频率+最后取高频的一个或者多个数

思路二(二叉搜索树)

  • 既然是搜索树,它中序遍历就是有序的
  • 遍历有序数组的元素出现频率从头遍历,那么⼀定是相邻两个元素作⽐较,然后就把出现频率最⾼的元素输出即可
  • 出现相邻两个元素的情况,可以使⽤pre指针和cur指针的技巧了
  • 需要注意初始化的时候pre = NULL,实际上比较的是第⼀个元素

统计众数出现次数的代码:

        if (pre==null){	// 第⼀个节点
            count=1;	// 频率为1
        } else if (pre.val==cur.val) {	// 与前⼀个节点数值相同
            count++;
        } else{			// 与前⼀个节点数值不同,则复原
            count=1;
        }

        pre = cur;		// 更新上⼀个节点

本题要求的是:返回众数集合/数组
1、正常逻辑第一遍先找出最⼤频率maxCount,然后重新遍历⼀遍数组把出现频率为maxCount的元素放进众数集合里,最终需要两遍

2、遍历一次数组(只需要遍历⼀遍⼆叉搜索树,就求出了众数的集合)

  • maxCount需要最⼤频率的时候保存
  • 频率count ⼤于 maxCount的时候,不仅要更新maxCount,⽽且要清空结果集,留着之前的结果集不对

实现代码

class Solution {
    TreeNode pre = null;
    int count = 0;		 // 统计频率
    int maxCount = 0;	 // 最⼤频率
    List<Integer> resList = new ArrayList<>();
    public int[] findMode(TreeNode root) {
        searchBST(root);	
        int[] result = new int[resList.size()];
        for (int i=0;i<resList.size();i++){
            result[i] = resList.get(i);
        }
        return result;
    }

    void searchBST(TreeNode cur){
        if (cur==null)return;
        searchBST(cur.left);	// 左
		// 中
        if (pre==null){		// 第⼀个节点
            count=1;
        } else if (pre.val==cur.val) {	// 与前⼀个节点数值相同
            count++;
        } else{		// 与前⼀个节点数值不同
            count=1;
        }

        pre = cur;		// 更新上⼀个节点

        if (maxCount==count)resList.add(cur.val);	// 如果和最⼤值相同,放进resList中
        if (count>maxCount){	// 计数⼤于最⼤值频率
            maxCount = count;	// 更新最⼤频率
            resList.clear();	// 很关键的⼀步,不要忘记清空resList,之前resList⾥的元素都失效了
            resList.add(cur.val);
        }
        searchBST(cur.right);	// 右
        return;
    }
}

最重要的一句话:做二叉树的题目,首先需要确认的是遍历顺序
大佬们有更好的方法,请不吝赐教,谢谢

你可能感兴趣的:(#,每日一道LeeCode算法题,算法,数据结构,leetcode,深度优先)