网易互娱 9.7 第二批 笔试 第二题 层次树
作者:互联网
输入:
2
8
2 -1 -1
1 5 3
4 -1 6
2 -1 -1
3 0 2
2 4 7
7 -1 -1
2 -1 -1
8
21 6 -1
52 4 -1
80 0 3
31 7 -1
21 -1 -1
59 -1 -1
50 5 -1
48 -1 1
输出:YES
NO
网易互娱 第二批笔试第二题 层次树 调了我一个小时,被自己蠢哭了。
大概题意是这样,有一个树以上面的形式给出,第一行N为测试用例个数,第二行为节点数M,接下来M行为每个节点的数据,行数为节点编号,第一个数为该节点的价值,接下来两个数为该节点的左右子节点的编号,-1表示子节点为空,如果这棵树每一层的价值的和比上一层严格大于,则输出“YES”,否则输出“NO”。
思路:刚开始想的是每个节点先构造一颗小树,后面将所有的小树合并成一颗大树,最后层次遍历判断是否符合条件,写到树的融合的时候有点写不下去了,转而换一个思路,先找到根节点,也就是不可能为其他节点子节点的那个节点就是根节点,然后从根节点开始查找子节点构造一颗完整的树,然后层次遍历判断并输出结果,以下是实现代码
#include "stdafx.h"
#include <iostream>
#include <string>
#include <string.h>
#include <vector>
#include <algorithm>
#include <iostream>
#include <set>
#include <algorithm>
#include <sstream>
#include <queue>
#include <iomanip>
#include <stack>
using namespace std;
struct TreeNode{
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int v) : val(v), left(nullptr), right(nullptr)
{
}
};
void preOrderThis(TreeNode* root)
{
if (root == nullptr)
{
return;
}
cout << root->val;
preOrderThis(root->left);
preOrderThis(root->right);
}
void creatTree(TreeNode* root_copy, int root_l, int root_r, vector<int>& leftIndex, vector<int>& rightIndex)
{
int tmp_l;
int tmp_r;
if(root_l != -1) {
TreeNode* leftNode = new TreeNode(root_l);
root_copy->left = leftNode;
tmp_l = root_l;
tmp_r = root_r;
root_l = leftIndex[leftNode->val];
root_r = rightIndex[leftNode->val];
creatTree(leftNode, root_l, root_r, leftIndex, rightIndex);
root_l = tmp_l;
root_r = tmp_r;
}
if(root_r != -1) {
TreeNode* rightNode = new TreeNode(root_r);
root_copy->right = rightNode;
tmp_l = root_l;
tmp_r = root_r;
root_l = leftIndex[rightNode->val];
root_r = rightIndex[rightNode->val];
creatTree(rightNode, root_l, root_r, leftIndex, rightIndex);
root_l = tmp_l;
root_r = tmp_r;
}
}
int main()
{
int N, M;
cin >> N;
int val, l, r;
queue<TreeNode*> queueNode;
vector<string> result;
vector<TreeNode*> rootList;
for (int i = 0; i < N; i++)
{
cin >> M;
int *value = new int[M];
memset(value, 0, M * sizeof(int*));
vector<int> leftIndex, rightIndex;
vector<int> count;
int rootindex = 0;
for (int j = 0; j < M; j++)
{
count.push_back(0);
}
for (int j = 0; j < M; j++)
{
cin >> val >> l >> r;
value[j] = val;
leftIndex.push_back(l);
rightIndex.push_back(r);
}
for (int j = 0; j < M; j++)
{
for (int q = 0; q < M; q++)
{
if (j == leftIndex[q] || j == rightIndex[q])
{
count[j] ++;
}
}
}
for (int j = 0; j < M; j++)
{
if (count[j] == 0)
{
rootindex = j;
}
}
TreeNode* rootNode = new TreeNode(rootindex);
int root_l = leftIndex[rootindex];
int root_r = rightIndex[rootindex];
TreeNode* root_copy = rootNode;
creatTree(root_copy, root_l, root_r, leftIndex, rightIndex);
preOrderThis(rootNode);
TreeNode* root = rootNode;
queueNode.push(root);
int num1 = 1, num2 = 0;
int sum = 0, lastSum = -1;
TreeNode* node = nullptr;
bool isOk = true;
bool ji_cen = false;
bool ou_cen = false;
while(num1 > 0 || num2 > 0) {
while(num1 > 0) {
ji_cen = true;
node = queueNode.front();
queueNode.pop();
sum += value[node->val];
if (node->left)
{
queueNode.push(node->left);
num2++;
}
if (node->right)
{
queueNode.push(node->right);
num2++;
}
num1--;
}
if (ji_cen && sum <= lastSum)
{
isOk = false;
break;
}
lastSum = sum;
sum = 0;
ji_cen = false;
while(num2 > 0) {
ou_cen = true;
node = queueNode.front();
queueNode.pop();
sum += value[node->val];
if (node->left)
{
queueNode.push(node->left);
num1++;
}
if (node->right)
{
queueNode.push(node->right);
num1++;
}
num2--;
}
if (ou_cen && sum <= lastSum)
{
isOk = false;
break;
}
lastSum = sum;
sum = 0;
ou_cen = false;
}
if (isOk)
{
result.push_back("YES");
} else {
result.push_back("NO");
}
isOk = true;
}
return 0;
}
第二天在网上看了一下别人的思路,发现自己还是太年轻,为啥要纠结去构造那颗树,直接每层遍历查找不就完了,唉!!!!!!!!!!!!!!!!!!!!!!!!!!!!
以下是摘取的别人的实现
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
typedef struct _node{
int id;
long long val;
int lid;
int rid;
}node;
vector<node> tree; //保存结点
queue<int> level; //层序遍历用的queue
int main()
{
int T,N;
cin>>T;
int v,l,r;
for(int i=0;i<T;i++)
{
cin>>N;
tree.clear();
tree.resize(N);
int hasp[1005]={0}; // 判断是否是root 没有parent的就是root
for(int j=0;j<N;j++)
{
cin>>v>>l>>r;
node temp;
temp.id=j;
temp.val=v;
temp.lid=l;
temp.rid=r;
tree[j]=temp;
if(l!=-1)
hasp[l]=1;
if(r!=-1)
hasp[r]=1;
}
int root;
for(int j=0;j<N;j++)
{
if(hasp[j]==0)
{
root=j;
break;
}
}
bool ans=true;
int v=root;
level.push(v);
int k;
long long thislevel; // 当前层的和
long long prelevel=0; //前一层的和
while(!level.empty())
{
k=level.size();
thislevel=0;
for(int j=0;j<k;j++)
{
v=level.front();
level.pop();
thislevel+=tree[v].val; //计算当前层的和
if(tree[v].lid!=-1) //push下一层的结点
level.push(tree[v].lid);
if(tree[v].rid!=-1)
level.push(tree[v].rid);
}
if(thislevel<=prelevel) //每一层要严格小于下一层
{
ans=false;
break;
}
prelevel=thislevel;
}
if(ans)
cout<<"YES"<<endl;
else
cout<<"NO"<<endl;
}
system("pause");
}
参考:
[1] https://www.nowcoder.com/discuss/249422?type=post&order=time&pos=&page=1
标签:node,9.7,TreeNode,互娱,val,int,笔试,include,root 来源: https://blog.csdn.net/qican_7/article/details/100620530