题目
- 题目描述
给定原始二叉树和参照二叉树(输入的二叉树均为满二叉树,二叉树节点的值范围为[1,1000],二叉树的深度不超过1000),现对原始二叉树和参照二又树中相同层级目值相同的节点进行消除,消除规则为原始二叉树和参照二又树中存在多个值相同的节点只能消除等数量的,消除后的节点变为无效节点,请按节点值出现频率从高到低输出消除后原始二叉树中有效节点的值(如果原始二叉树消除后没有有效节点返回0)。
- 解答要求
时间限制: C/C++ 1000ms, 其他语言:2000ms
内存限制: C/C++256MB,其他语言:512MB
- 输入
原始二叉树中的节点个数
原始二叉树
参照二叉树中的节点个数
畚照二叉树
- 输出
原始二叉树中有效节点的值,按出现频率从高到低排序(相同频率的值按大小排序),相同频率的值按降序排列。
- 样例1
输入:
7
1 3 3 3 4 5 6
3
2 3 4
输出:
36541
解释:
原始二叉树A消除参照二叉树B中的重复元素后,有效节点剩余2个3,1个6,1个5,1个4,1个1,3出现的频率2,6、5、4、1出现的频率为1,按值从大到小排序,所以排序结果为36541。
- 样例2
输入:
15
5 6 6 6 7 7 7 8 8 9 9 7 7 5 6
7
5 6 6 7 7 8 8
输出:
79865
解释:
原始二叉树A消除参照二叉树B中的重复元素后,有效节点剩余3个7,2个9,2个8,2个6,1个5,8出现的频率为3,7出现的频率为2,6出现的频率为2,6的值比5大,所以排序结果为79865
- 样例3
输入:
7
1 3 4 3 2 2 6
3
2 4 3
输出:
2631
解释:
原始二叉树A消除参照二叉树B中的重复元素后,有效节点剩余2个2,1个6,1个3,1个1;2出现的频率2,6、3、1出现的频率为1,按值从大到小排序,所以排序结果为2631。
解题思路
- main 函数内分别 构造两个 vector 存入原始二叉树和参照二叉树的信息 ,构造1个结果map表示原始参考树剩余有效节点及其数量,初始化层数 n2=0。
- 遍历提取出原始二叉树和参考二叉树每一层的数据
对二叉树的第i个元素进行遍历,判断当前元素是否是该层的首元素(i==pow(2,n2-1)),若不是则继续遍历;若该元素是该层的首元素,则 提取出原始二叉树和参考二叉树中该层的所有元素,分别存入两个 map,表示该层节点的数值及其数量。
遍历参考树该层的节点,对原始树该层的数据抵消,最后存储剩余节点及数量
对参考树该层的数据进行遍历,并在原始二叉树中查找该数据,若能找到,则把该数据在原始二叉树这一层的数量 减去 在参考二叉树这一层的数量。
对原始参考树该层的数据进行遍历,若该数据的数量大于0,则表示该数据为有效节点,则将该数据及其数量存入结果map中。该层处理结束后,将层数n2++,继续遍历下一个节点i+1的元素。
- 若结果中有效节点数为空则直接输出0,否则按照节点数和节点数值排序输出。
构造1个vector用于排序,vector中的每一个元素都是一个 pair<int,int> ,表示剩余有效节点及其数量。构造1个排序规则函数对这个vector进行排序:若节点数相同则按照节点数值排序,否则按照节点数量排序。
代码
BUG 代码
- BUG 代码:没有考虑样例3这样的情况,该代码只是按照相同位置的相同元素进行了抵消,应当按照每一层的相同元素进行抵消。
#include <iostream>
#include <vector>
#include <map>
#include <algorithm>
using namespace std;
bool compare(const pair<int, int>& a, const pair<int, int>& b) {
if (a.second == b.second) {
return a.first > b.first;
}
return a.second > b.second;
}
int main() {
int n, m;
vector<int> res_vec;
cin >> n;
vector<int> n_vec(n);
for (int i = 0; i < n; ++i) {
cin >> n_vec[i];
}
cin >> m;
vector<int> m_vec(m);
for (int i = 0; i < m; ++i) {
cin >> m_vec[i