leetcode_二叉树验证(BFS、哈希集合)

题目描述:

二叉树上有 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;
    }
};
原文地址:https://www.cnblogs.com/missouter/p/12622117.html