📌  相关文章
📜  给定二叉树中最频繁的子树总和

📅  最后修改于: 2021-04-25 00:10:15             🧑  作者: Mango

给定二叉树,任务是找到可以通过将给定树的每个节点视为子树的根来获得的最频繁的子树总和。如果存在多个这样的总和,则将它们全部打印出来。

例子:

方法:对给定的树使用DFS遍历的想法来解决给定的问题。请按照以下步骤解决问题:

  • 创建两个辅助哈希映射MF ,其中M是一组整数键和相应的列表, F将存储每个数字的频率。
  • 对给定的树执行DFS遍历,然后执行以下操作:
    • 如果节点为NULL ,则返回0
    • 初始化变量左侧右侧,该变量存储当前节点的左侧子树和右侧子树的节点总和的值。
    • 找到currentNode.value +左+右的总和,将其存储在变量totalSum中
    • 现在更新映射FtotalSum的频率。
    • 将值F [totalSum]的频率更新为映射M中的totalSum
    • 从当前递归函数将值返回到totalSum
  • 完成上述步骤后,打印列表M.rbegin()的所有元素。

下面是上述方法的实现:

C++
// C++ program for the above approach
#include 
using namespace std;
  
// Function to print the vector
void printVector(vector v)
{
    // Traverse vector c
    for (int i = 0; i < v.size(); i++) {
        cout << v[i] << " ";
    }
}
  
// TreeNode class
class TreeNode {
public:
    int val;
    TreeNode *left, *right;
  
    // Constructor
    TreeNode(int data)
    {
        val = data;
        left = NULL;
        right = NULL;
    }
};
  
// Function to insert node in the
// binary tree
void insert(TreeNode** root, int val)
{
    // Initialize Queue
    queue q;
  
    // Push the node root
    q.push(*root);
  
    // While Q.size() is there
    while (q.size()) {
  
        // Get the front node
        TreeNode* temp = q.front();
        q.pop();
  
        // If left is NULL
        if (!temp->left) {
            if (val)
                temp->left = new TreeNode(val);
            else
                temp->left = new TreeNode(0);
            return;
        }
        else {
            q.push(temp->left);
        }
  
        // If right is NULL
        if (!temp->right) {
            if (val)
                temp->right = new TreeNode(val);
            else
                temp->right = new TreeNode(0);
            return;
        }
        else {
            q.push(temp->right);
        }
    }
}
  
// Function to make the tree from
// given node values
TreeNode* buildTree(vector v)
{
    TreeNode* root = new TreeNode(v[0]);
  
    // Traverse and insert node
    for (int i = 1; i < v.size(); i++) {
        insert(&root, v[i]);
    }
    return root;
}
  
// Utility function to find subtree
// sum with highest frequency of a
// particular node
int findsubTreeSumUtil(
    TreeNode* node, map >& mpp,
    map& frequency)
{
    if (!node)
        return 0;
  
    // Recur for the left subtree
    int left = findsubTreeSumUtil(
        node->left, mpp, frequency);
  
    // Recur for the right subtree
    int right = findsubTreeSumUtil(
        node->right, mpp, frequency);
  
    // Stores sum of nodes of a subtree
    int totalSum = node->val + left + right;
  
    // Update the frequency
    if (!frequency.count(totalSum)) {
        mpp[1].push_back(totalSum);
        frequency[totalSum] = 1;
    }
    else {
        frequency[totalSum]++;
        mpp[frequency[totalSum]].push_back(totalSum);
    }
  
    // Return the total sum
    return totalSum;
}
  
// Function to find subtree sum with
// highest frequency of given tree
void findsubTreeSum(TreeNode* root)
{
    // Store list of nodes attached to
    // a particular node and frequency
    // of visited nodes
    map > mpp;
    map frequency;
  
    // Base Case
    if (!root) {
        printVector({});
        return;
    }
  
    // DFS function call
    findsubTreeSumUtil(root, mpp, frequency);
  
    // Print the vector
    printVector(mpp.rbegin()->second);
}
  
// Driver Code
int main()
{
    // Given nodes of the tree
    vector v = { 5, 2, -4 };
  
    // Function call to build the tree
    TreeNode* tree = buildTree(v);
  
    // Function Call
    findsubTreeSum(tree);
  
    return 0;
}


输出:
2 -4 3

时间复杂度: O(N)
辅助空间: O(N)