📌  相关文章
📜  检查给定的排列是否是给定树的有效BFS

📅  最后修改于: 2021-04-22 07:28:00             🧑  作者: Mango

给定一棵树,其中N个节点的编号从1到N ,数字排列数组从1到N。检查是否可以通过在给定的树上应用BFS(宽度优先遍历)来获得给定的排列数组。
注意:遍历将始终从1开始。
例子:

方法:要解决上述问题,我们必须遵循以下步骤:

  • 在BFS中,我们访问当前节点的所有邻居,并按顺序将其子级推入队列,然后重复此过程,直到队列不为空。
  • 假设有两个根节点:A和B。我们可以自由选择首先访问哪个。假设我们先访问A,但是现在我们必须将A的子代推入队列,而我们不能在A之前访问B的子代。
  • 因此,基本上,我们可以按任何顺序访问特定节点的子级,但是固定访问2个不同节点的子级的顺序是固定的,即如果A在B之前访问,则A的所有子级应该在所有访问之前访问。 B的孩子
  • 我们将做同样的事情。我们将创建一个集合队列,在每个集合中,我们将推送特定节点的子代并一起遍历排列。如果在队列顶部的集合中找到排列的当前元素,那么我们将继续进行操作,否则将返回false。

下面是上述方法的实现:

C++
// C++ implementation to check if the
// given permutation is a valid
// BFS of a given tree
#include 
using namespace std;
 
// map for storing the tree
map > tree;
 
// map for marking
// the nodes visited
map vis;
 
// Function to check if
// permutation is valid
bool valid_bfs(vector& v)
{
    int n = (int)v.size();
    queue > q;
    set s;
    s.insert(1);
 
    /*inserting the root in
     the front of queue.*/
    q.push(s);
    int i = 0;
 
    while (!q.empty() && i < n)
    {
 
        // If the current node
        // in a permutation
        // is already visited
        // then return false
        if (vis.count(v[i]))
        {
            return 0;
        }
        vis[v[i]] = 1;
 
        // if all the children of previous
        // nodes are visited then pop the
        // front element of queue.
        if (q.front().size() == 0)
        {
            q.pop();
        }
 
        // if the current element of the
        // permutation is not found
        // in the set at the top of queue
        // then return false
        if (q.front().find(v[i])
            == q.front().end()) {
            return 0;
        }
        s.clear();
 
        // push all the children of current
        // node in a set and then push
        // the set in the queue.
        for (auto j : tree[v[i]]) {
            if (vis.count(j)) {
                continue;
            }
            s.insert(j);
        }
        if (s.size() > 0) {
            set temp = s;
            q.push(temp);
        }
        s.clear();
 
        // erase the current node from
        // the set at the top of queue
        q.front().erase(v[i]);
 
        // increment the index
        // of permutation
        i++;
    }
 
    return 1;
}
 
// Driver code
int main()
{
    tree[1].push_back(2);
    tree[2].push_back(1);
    tree[1].push_back(5);
    tree[5].push_back(1);
    tree[2].push_back(3);
    tree[3].push_back(2);
    tree[2].push_back(4);
    tree[4].push_back(2);
    tree[5].push_back(6);
    tree[6].push_back(5);
 
    vector arr
        = { 1, 5, 2, 3, 4, 6 };
 
    if (valid_bfs(arr))
        cout << "Yes" << endl;
 
    else
        cout << "No" << endl;
 
    return 0;
}
 
// This code is contributed by rutvik_56


Java
// Java implementation to check if the
// given permutation is a valid
// BFS of a given tree
import java.util.*;
class GFG{
 
// Map for storing the tree
static HashMap > tree =
                         new HashMap<>();
 
// Map for marking
// the nodes visited
static HashMap vis =
                        new HashMap<>();
 
// Function to check if
// permutation is valid
static boolean valid_bfs(List v)
{
  int n = (int)v.size();
  Queue > q =
                new LinkedList<>();
  HashSet s = new HashSet<>();
  s.add(1);
 
  // Inserting the root in
  // the front of queue.
  q.add(s);
  int i = 0;
 
  while (!q.isEmpty() && i < n)
  {
    // If the current node
    // in a permutation
    // is already visited
    // then return false
    if (vis.containsKey(v.get(i)))
    {
      return false;
    }
 
    vis.put(v.get(i), 1);
 
    // If all the children of previous
    // nodes are visited then pop the
    // front element of queue.
    if (q.peek().size() == 0)
    {
      q.remove();
    }
 
    // If the current element of the
    // permutation is not found
    // in the set at the top of queue
    // then return false
    if (!q.peek().contains(v.get(i)))
    {
      return false;
    }
    s.clear();
 
    // Push all the children of current
    // node in a set and then push
    // the set in the queue.
    for (int j : tree.get(v.get(i)))
    {
      if (vis.containsKey(j))
      {
        continue;
      }
      s.add(j);
    }
    if (s.size() > 0)
    {
      HashSet temp = s;
      q.add(temp);
    }
    s.clear();
 
    // Erase the current node from
    // the set at the top of queue
    q.peek().remove(v.get(i));
 
    // Increment the index
    // of permutation
    i++;
  }
  return true;
}
 
// Driver code
public static void main(String[] args)
{
  for (int i = 1; i <= 6; i++)
  {
    tree.put(i, new Vector());
  }
   
  tree.get(1).add(2);
  tree.get(2).add(1);
  tree.get(1).add(5);
  tree.get(5).add(1);
  tree.get(2).add(3);
  tree.get(3).add(2);
  tree.get(2).add(4);
  tree.get(4).add(2);
  tree.get(5).add(6);
  tree.get(6).add(5);
 
  Integer []arr1 = {1, 5, 2, 3, 4, 6};
  List arr = Arrays.asList(arr1);
 
  if (valid_bfs(arr))
    System.out.print("Yes" + "\n");
  else
    System.out.print("No" + "\n");
}
}
 
// This code is contributed by Princi Singh


Python3
# Python3 implementation to check if the
# given permutation is a valid
# BFS of a given tree
  
# map for storing the tree
tree=dict()
  
# map for marking
# the nodes visited
vis=dict()
  
# Function to check if
# permutation is valid
def valid_bfs( v):
 
    n = len(v)
     
    q=[]
    s=set()
    s.add(1);
  
    '''inserting the root in
     the front of queue.'''
    q.append(s);
    i = 0;
  
    while (len(q)!=0 and i < n):
  
        # If the current node
        # in a permutation
        # is already visited
        # then return false
        if (v[i] in vis):
            return 0;
         
        vis[v[i]] = 1;
  
        # if all the children of previous
        # nodes are visited then pop the
        # front element of queue.
        if (len(q[0])== 0):
            q.pop(0);
  
        # if the current element of the
        # permutation is not found
        # in the set at the top of queue
        # then return false
        if (v[i] not in q[0]):
            return 0;
         
        s.clear();
  
        # append all the children of current
        # node in a set and then append
        # the set in the queue.
        for j in tree[v[i]]:
         
            if (j in vis):
                continue;
             
            s.add(j);
         
        if (len(s) > 0):
             
            temp = s;
            q.append(temp);
         
        s.clear();
  
        # erase the current node from
        # the set at the top of queue
        q[0].discard(v[i]);
  
        # increment the index
        # of permutation
        i+=1
  
    return 1;
 
  
# Driver code
if __name__=="__main__":
 
    tree[1]=[]
    tree[2]=[]
    tree[5]=[]
    tree[3]=[]
    tree[2]=[]
    tree[4]=[]
    tree[6]=[]
    tree[1].append(2);
    tree[2].append(1);
    tree[1].append(5);
    tree[5].append(1);
    tree[2].append(3);
    tree[3].append(2);
    tree[2].append(4);
    tree[4].append(2);
    tree[5].append(6);
    tree[6].append(5);
  
    arr = [ 1, 5, 2, 3, 4, 6 ]
  
    if (valid_bfs(arr)):
        print("Yes")
    else:
        print("No")


C#
// C# implementation to check
// if the given permutation
// is a valid BFS of a given tree
using System;
using System.Collections.Generic;
class GFG{
 
// Map for storing the tree
static Dictionary> tree = new Dictionary>();
 
// Map for marking
// the nodes visited
static Dictionary vis = new Dictionary();
 
// Function to check if
// permutation is valid
static bool valid_bfs(List v)
{
  int n = (int)v.Count;
  Queue> q =
        new Queue>();
  HashSet s = new HashSet();
  s.Add(1);
 
  // Inserting the root in
  // the front of queue.
  q.Enqueue(s);
  int i = 0;
 
  while (q.Count != 0 && i < n)
  {
    // If the current node
    // in a permutation
    // is already visited
    // then return false
    if (vis.ContainsKey(v[i]))
    {
      return false;
    }
 
    vis.Add(v[i], 1);
 
    // If all the children of previous
    // nodes are visited then pop the
    // front element of queue.
    if (q.Peek().Count == 0)
    {
      q.Dequeue();
    }
 
    // If the current element of the
    // permutation is not found
    // in the set at the top of queue
    // then return false
    if (!q.Peek().Contains(v[i]))
    {
      return false;
    }
     
    s.Clear();
 
    // Push all the children of current
    // node in a set and then push
    // the set in the queue.
    foreach (int j in tree[v[i]])
    {
      if (vis.ContainsKey(j))
      {
        continue;
      }
      s.Add(j);
    }
    if (s.Count > 0)
    {
      HashSet temp = s;
      q.Enqueue(temp);
    }
    s.Clear();
 
    // Erase the current node from
    // the set at the top of queue
    q.Peek().Remove(v[i]);
 
    // Increment the index
    // of permutation
    i++;
  }
  return true;
}
 
// Driver code
public static void Main(String[] args)
{
  for (int i = 1; i <= 6; i++)
  {
    tree.Add(i, new List());
  }
 
  tree[1].Add(2);
  tree[2].Add(1);
  tree[1].Add(5);
  tree[5].Add(1);
  tree[2].Add(3);
  tree[3].Add(2);
  tree[2].Add(4);
  tree[4].Add(2);
  tree[5].Add(6);
  tree[6].Add(5);
 
  int []arr1 = {1, 5, 2, 3, 4, 6};
  List arr = new List();
  arr.AddRange(arr1);
 
  if (valid_bfs(arr))
    Console.Write("Yes" + "\n");
  else
    Console.Write("No" + "\n");
}
}
 
// This code is contributed by Princi Singh


输出:
No

时间复杂度: O(N * log N)
相似的文章:检查给定的排列是否是图的有效DFS