【剑指Offer-树】二叉搜索树中的众数

题目描述

给定一个有相同值的二叉搜索树(BST),找出 BST 中的所有众数(出现频率最高的元素)。
假定 BST 有如下定义:

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

示例:

例如:
给定 BST [1,null,2,2],
   1
    \
     2
    /
   2
返回[2].

题目链接: https://leetcode-cn.com/problems/find-mode-in-binary-search-tree/

思路

二叉搜索树有一个重要的性质:二叉搜索树的中序遍历序列是升序序列。所以我们中序遍历二叉搜索树记录节点值的升序序列,然后根据升序序列找众数。找众数的方法:

  • 将序列第一个元素放入结果中,将当前元素出现的最多次数记为curMax并初始化为1,将当前元素的出现次数cnt记为1;
  • 从第二个元素开始遍历,如果当前元素和前一个元素相等,则cnt++;
    • 如果cnt==curMax,则将当前元素假如结果中;
    • 如果cnt>curMax,说明找到了出现次数更多的众数,则将结果清空,将当前元素加入到结果中;
  • 如果当前元素和前一个元素不等,则将cnt置为1.

代码如下:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    vector<int> findMode(TreeNode* root) {
        if(root==nullptr) return {};

        vector<int> v;
        inOrder(root, v);
        
        int cnt = 1;
        int curMax = 1;
        vector<int> ans;
        ans.push_back(v[0]);
        for(int i=1; i<v.size(); i++){
            if(v[i]==v[i-1]){
                cnt++;
            }else cnt=1;
            if(cnt==curMax){
                ans.push_back(v[i]);
            }else if(cnt>curMax){
                curMax = cnt;
                ans.clear();
                ans.push_back(v[i]);
            }
        }
        return ans;
    }

    void inOrder(TreeNode* root, vector<int>& v){
        if(root==nullptr) return;

        inOrder(root->left, v);
        v.push_back(root->val);
        inOrder(root->right, v);
    }
    
};
  • 时间复杂度:O(h+n)
    h为树深度,n为节点个数。
  • 空间复杂度:O(n)
    n为节点个数。

猜你喜欢

转载自www.cnblogs.com/flix/p/12694990.html