二叉搜索树中节点/值的频率

Frequency of Node/value in a binary search tree

本文关键字:频率 节点 搜索树      更新时间:2023-10-16

给定一个二叉搜索树,其中可能包含重复项,但BST的所有其他逻辑都是完整的,确定最频繁出现的元素。

class TreeNode
{
public:
    TreeNode* right = NULL;
    TreeNode* left = NULL;
    int val;
    TreeNode(int value)
    {
        val = value;
    }
};
// To keep track of the frequency of the value/node
struct holder
{
public:
    TreeNode* most = NULL;
    int count = 0;
};
int frequencyOfNode(TreeNode* root, struct holder* ptr)
{
    if (root == NULL)
    {
        return 0;
    }
    int left = frequencyOfNode(root->left, ptr);
    int right = frequencyOfNode(root->right, ptr);
// need to check of left and right are nor null
    if (left != 0 && root->val == root->left->val)
    {
        return 1 + left;
    }
    else if (right != 0 && root->val == root->right->val)
    {
        return 1 + right;
    }
    else
    {
        // left has a higher frequency
        if (left >= right)
        {
            // left is bigger;
            if (left > ptr->count)
            {
                ptr->most = root->left;
                ptr->count = left;
            }
        }
        else
        {
            // right has a higher frequency
            if (right > ptr->count)
            {
                ptr->most = root->right;
                ptr->count = right;
            }
        }
        return 1;
    }
}

我正在对二叉搜索树进行后序遍历。当节点以连续顺序出现时,我的逻辑有效,但如果节点不是以连续顺序出现;重置节点频率。

我的时间是O(n),空间是O(1)。

问题是当节点没有连续链接时。

我的示例树:

int main()
{
    TreeNode *root = new TreeNode(6);
    root->right = new TreeNode(8);
    root->right->left = new TreeNode(7);
    root->right->right = new TreeNode(8);
    root->right->right->right = new TreeNode(8);
    root->right->right->right->right = new TreeNode(9);
    root->right->right->right->right->left = new TreeNode(8);
    root->left = new TreeNode(4);
    root->left->right = new TreeNode(5);
    root->left->right->right = new TreeNode(5);
    root->left->right->right->right = new TreeNode(5);
    root->left->left = new TreeNode(1);
    root->left->left->right = new TreeNode(1);
    root->left->left->right->right = new TreeNode(1);
    root->left->left->right->right = new TreeNode(2);
    root->left->left->left = new TreeNode(0);
    struct holder freq;
    int ran = frequencyOfNode(root, &freq);
    std::cout << "random" << ran << std::endl;
    std::cout << "The Node: " << freq.most->val << " frequency " << freq.count
            << std::endl;
    return 0;
}

我真的很困惑如何考虑,当节点不是连续的(即8->8->8->9->8)。

我看你已经自己解决了一些问题。无论如何,我决定彻底解决这个问题,同时改变一些东西来简化一切。它占用O(N)个时间和O(1)个空间:

#include <iostream>
#include <limits>
class TreeNode
{
public:
    TreeNode* right;
    TreeNode* left;
    int val;
    TreeNode(int value)
    {
        val = value;
        right = left = NULL;
    }
};
// To keep track of the frequency of the value/node
struct Holder
{
public:
    int value;
    int count;
    Holder(int v=std::numeric_limits<int>::min(), int c=-1): value(v), count(c) {}
};

void dfs(TreeNode* root, int &mostFrequent, int &mostFrequentCount, int &current, int &currentCount)
{
    if(root->left) dfs(root->left, mostFrequent, mostFrequentCount, current, currentCount); //first go to smaller
    int val = root->val;
    if(val == current) currentCount++;
    else { current=val; currentCount=1; }
    if(currentCount > mostFrequentCount) 
    {
        mostFrequent=current;
        mostFrequentCount=currentCount;
    }
    if(root->right) dfs(root->right, mostFrequent, mostFrequentCount, current, currentCount); //finally go to larger
}
Holder getMostFrequent(TreeNode *root)
{
    int mostFrequent=-1,mostFrequentCount=-1, current=std::numeric_limits<int>::min(), currentCount=-1;
    if(root) dfs(root, mostFrequent, mostFrequentCount, current, currentCount);
    return Holder(mostFrequent, mostFrequentCount);
}

int main()
{
    TreeNode *root = new TreeNode(6);
    root->right = new TreeNode(8);
    root->right->left = new TreeNode(7);
    root->right->right = new TreeNode(8);
    root->right->right->right = new TreeNode(8);
    root->right->right->right->right = new TreeNode(9);
    root->right->right->right->right->left = new TreeNode(8);
    root->left = new TreeNode(4);
    root->left->right = new TreeNode(5);
    root->left->right->right = new TreeNode(5);
    root->left->right->right->right = new TreeNode(5);
    root->left->left = new TreeNode(1);
    root->left->left->right = new TreeNode(1);
    root->left->left->right->right = new TreeNode(1);
    root->left->left->right->right = new TreeNode(2);
    root->left->left->left = new TreeNode(0);
    Holder h = getMostFrequent(root);
    std::cout << "most frequently encountered element: " << h.value << ", " << h.count << " timesn";

    return 0;
}

它利用了这样一个事实,因为这是一个BST,按[left -> current -> right]的顺序遍历它会得到排序的元素,就这样。