zoukankan      html  css  js  c++  java
  • 【LeetCode-树】二叉搜索树中的众数

    题目描述

    给定一个有相同值的二叉搜索树(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为节点个数。

    写法二
    使用迭代,代码如下:

    /**
     * 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 {};
    
            int maxCnt = INT_MIN;
            int cnt = 0;    // 保存当前数字的计数
            int pre = -1;   // 保存前一个数字
            vector<int> ans;
            stack<pair<TreeNode*, int>> s;
            s.push(make_pair(root, 0));
            while(!s.empty()){
                TreeNode* curNode = s.top().first;
                int visit = s.top().second;
                s.pop();
                if(visit==0){
                    if(curNode->right!=nullptr) s.push(make_pair(curNode->right, 0));
                    s.push(make_pair(curNode, 1));
                    if(curNode->left!=nullptr) s.push(make_pair(curNode->left, 0));
                }else{
                    if(pre!=-1){    // 不是第一个数字
                        if(curNode->val==pre){
                            cnt++;
                            if(cnt>maxCnt){ // 找到了新的众数
                                ans.clear();
                                ans.push_back(curNode->val);
                                maxCnt = cnt;
                            }else if(cnt==maxCnt){  // 找到了出现次数一样的众数
                                ans.push_back(curNode->val);
                            }
                        }else{
                            cnt = 1;
                            if(cnt==maxCnt){    // 防止树中只有两个节点的情况
                                ans.push_back(curNode->val);
                            }
                        }
                    }else{
                        cnt = 1;
                        maxCnt = cnt;
                        ans.push_back(curNode->val);    // 防止树中只有一个节点的情况
                    }
                    pre = curNode->val;
                }
            }
            return ans;
        }
    };
    
    • 时间复杂度:O(n)
    • 空间复杂度:O(h)
      h为树高。
  • 相关阅读:
    结对作业
    小学算术题四则运算(升级)
    自动生成小学四则运算题目(Python实现)
    《基于CMMI的软件工程及实训指导》第一章 软件工程基础
    使用 python 进行微信好友分析
    中国大学排名
    python小程序测试
    爬虫测试
    体育竞技分析

  • 原文地址:https://www.cnblogs.com/flix/p/12694990.html
Copyright © 2011-2022 走看看