[Sword Finger Offer-tree]バイナリ検索ツリーのモード

タイトルの説明

同じ値の二分探索木(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に初期化して、現在の要素の出現回数を1として記録します。
  • 2番目の要素からトラバースを開始します。現在の要素と前の要素が等しい場合は、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