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

📅  最后修改于: 2021-10-27 09:11:31             🧑  作者: Mango

给定一棵二叉树,任务是通过将给定树的每个节点作为子树的根来找到可以得到的最频繁的子树和。如果存在多个这样的总和,则打印所有这些总和。

例子:

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

  • 创建两个辅助哈希映射MF ,其中M是一组整数键和对应的列表, F将存储每个数字的频率。
  • 对给定的树执行 DFS 遍历并执行以下操作:
    • 如果节点为NULL ,则返回0
    • 初始化变量leftright ,用来存储当前节点左右子树节点之和的值。
    • 找到currentNode.value + left + right的总和,将其存储在变量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)

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程