给定一棵二叉树,任务是通过将给定树的每个节点作为子树的根来找到可以得到的最频繁的子树和。如果存在多个这样的总和,则打印所有这些总和。
例子:
Input:
5
/ \
2 -4
Output: 2 -4 3
Explanation:
The sum of nodes considering 5 as the root of subtree is 5 + 2 – 4 = 3.
The sum of nodes considering 2 as the root of subtree is 2 = 2.
The sum of nodes considering -4 as the root of subtree is -4 = -4.
Since all the sums have same frequency, print all the sum.
Input:
4
/ \
2 -4
Output: 2
Explanation:
The sum of nodes considering 4 as the root of subtree is 4 + 2 – 4 = 2.
The sum of nodes considering 2 as the root of subtree is 2 = 2.
The sum of nodes considering -4 as the root of subtree is -4 = -4.
Since, sum 2 has maximum frequency ( = 2). Hence, print the value 2.
方法:使用给定树的 DFS 遍历来解决给定问题的想法。请按照以下步骤解决问题:
- 创建两个辅助哈希映射M和F ,其中M是一组整数键和对应的列表, F将存储每个数字的频率。
- 对给定的树执行 DFS 遍历并执行以下操作:
- 如果节点为NULL ,则返回0 。
- 初始化变量left和right ,用来存储当前节点左右子树节点之和的值。
- 找到currentNode.value + left + right的总和,将其存储在变量totalSum 中。
- 现在更新地图F中totalSum的频率。
- 将值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 现场工作专业课程和学生竞争性编程现场课程。