题目描述:
二叉树上有 n 个节点,按从 0 到 n - 1 编号,其中节点 i 的两个子节点分别是 leftChild[i] 和 rightChild[i]。
只有 所有 节点能够形成且 只 形成 一颗 有效的二叉树时,返回 true;否则返回 false。
如果节点 i 没有左子节点,那么 leftChild[i] 就等于 -1。右子节点也符合该规则。
注意:节点没有值,本问题中仅仅使用节点编号。
这题算是一个非常中规中矩的二叉树题…给出每个结点的左右孩子结点序列,判断它是不是二叉树。
从下面几个方面排除:
1.有结点入度多于1的情况肯定是不对的;
2.存在多个入度为零的点(根)是有问题的,题目写明只有一棵二叉树;
对于第一种情况,先找到根节点,然后bfs遍历,若多次遍历到一个结点,返回false;
这里的bfs用到了stl库中的unordered_set,简单用法为:
#include<unorder_set> #include<iostream> using namespace std; int main(){ unorder_set<int> wow; int x=2; wow.insert(x); //将x添加至哈希集合wow中 bool y=wow.count(2); //查找哈希集合中是否有2,只返回0或1
int z=wow.size(); //返回哈希集合元素个数 return 0; }
通过构造哈希集合,将bfs遍历到的元素加入集合中,利用count查询集合是否已经包含了该元素;
第二种情况的解决思路很简单,bfs将树中元素全部遍历,若存在未遍历到的点,则最后集合中元素个数会与题目给出的n不符合,在代码最后返回set.size()==n即可。
贴代码:
class Solution { public: bool validateBinaryTreeNodes(int n, vector<int>& leftChild, vector<int>& rightChild) { int rudu[10010]={0}; for(int i=0;i<n;i++){ if(leftChild[i]!=-1) rudu[leftChild[i]]++; if(rightChild[i]!=-1) rudu[rightChild[i]]++; } int root=-1; for(int i=0;i<n;i++){ if(rudu[i]==0){ root=i; break; } } if(root==-1) return false; unordered_set <int> seen; seen.insert(root); queue <int> q; q.push(root); while(!q.empty()){ int x=q.front(); q.pop(); if(leftChild[x]!=-1){ if(seen.count(leftChild[x])) return false; seen.insert(leftChild[x]); q.push(leftChild[x]); } if(rightChild[x]!=-1){ if(seen.count(rightChild[x])) return false; seen.insert(rightChild[x]); q.push(rightChild[x]); } } return seen.size()==n; } };