📌  相关文章
📜  检查给定的数组是否有唯一的最短公共超序列

📅  最后修改于: 2022-05-13 01:57:52.157000             🧑  作者: Mango

检查给定的数组是否有唯一的最短公共超序列

给定一个大小为N*M二维数组arr[][] ,它表示N个数组,每个数组的大小为M 。任务是检查所有这些数组是否具有唯一的公共超序列。

例子:

方法:思想是使用拓扑排序,按照下面提到的步骤解决问题:

  • 用有向图表示arr[][] ”中的序列,求其拓扑排序顺序
  • 如果只有一个拓扑排序顺序,那么可以说只有一个最短公共超序列
  • 否则,返回假。

下面是上述方法的实现。

C++
// C++ code for the above approach
#include 
using namespace std;
 
// Function to check unique
// shortest common supersequence
bool shortestSuperSeq(vector >& arr,
                      int N, int M)
{
    // Initializing map to store
    // edges and indegree of vertices
    unordered_map > adj;
    unordered_map indegree;
 
    // Initializing all keys of map
    // with values of sequences in arr
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < M; j++) {
            int node = arr[i][j];
            adj[node] = {};
            indegree[node] = 0;
        }
    }
 
    // For every sequence in arr
    // calculate indegree and edges.
    for (auto seq : arr) {
        for (int i = 1; i < M; i++) {
            adj[seq[i - 1]].push_back(seq[i]);
            indegree[seq[i]]++;
        }
    }
 
    // Vector to store
    // topologically sorted order.
    vector res;
    queue q;
 
    // Push vertices with 0 indegree in queue
    for (auto itr : indegree) {
        if (itr.second == 0) {
            q.push(itr.first);
        }
    }
 
    while (!q.empty()) {
        int size = q.size();
 
        // If size of q > 1, this means
        // more than one choices,
        // so no unique common supersequence
        // can be formed.
        if (size != 1)
            return false;
 
        int node = q.front();
 
        // Add node to topological sort order
        res.push_back(node);
 
        q.pop();
 
        // Decrement indegree of all
        // the vertices connected to node
        for (int i = 0; i < adj[node].size();
             i++) {
            int connected_node = adj[node][i];
 
            // Push vertices with 0 indegree
            // to queue
            if ((--indegree[connected_node])
                == 0) {
                q.push(connected_node);
            }
        }
    }
 
    // If indegree of any vertices is not 0,
    // return false.
    for (auto itr : indegree) {
        if (itr.second != 0)
            return false;
    }
 
    return true;
}
 
// Driver Code
int main()
{
    vector > arr = { { 1, 2 },
                                 { 1, 3 } };
    int N = arr.size(), M = arr[0].size();
    if (shortestSuperSeq(arr, N, M))
        cout << "True\n";
    else
        cout << "False\n";
    return 0;
}


Java
import java.io.*;
import java.util.*;
 
class GFG {
 
    // Function to check unique
    // shortest common supersequence
    public static boolean
    shortestSuperSeq(ArrayList > arr,
                     int N, int M)
    {
       
        // Initializing map to store
        // edges and indegree of vertices
        HashMap > adj
            = new HashMap<>();
        HashMap indegree
            = new HashMap<>();
 
        // Initializing all keys of map
        // with values of sequences in arr
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < M; j++) {
                int node = arr.get(i).get(j);
                ArrayList temp
                    = new ArrayList();
                adj.put(node, temp);
                indegree.put(node, 0);
            }
        }
 
        // For every sequence in arr
        // calculate indegree and edges.
 
        for (ArrayList seq : arr) {
            for (int i = 1; i < M; i++) {
                adj.get(seq.get(i - 1)).add(seq.get(i));
                int temp = indegree.get(seq.get(i));
                indegree.put(seq.get(i), temp + 1);
            }
        }
 
        // ArrayList to store
        // topologically sorted order.
        ArrayList res = new ArrayList();
        ArrayDeque q = new ArrayDeque<>();
 
        // Push vertices with 0 indegree in queue
        for (int itr : indegree.keySet()) {
            if (indegree.get(itr) == 0) {
                q.addLast(itr);
            }
        }
 
        while (q.size() > 0) {
            int size = q.size();
 
            // If size of q > 1, this means
            // more than one choices,
            // so no unique common supersequence
            // can be formed.
            if (size != 1)
                return false;
 
            int node = q.getFirst();
 
            // Add node to topological sort order
            res.add(node);
 
            q.removeLast();
 
            // Decrement indegree of all
            // the vertices connected to node
            for (int i = 0; i < adj.get(node).size(); i++) {
                int connected_node = adj.get(node).get(i);
 
                // Push vertices with 0 indegree
                // to queue
 
                int temp = indegree.get(connected_node) - 1;
                indegree.put(connected_node, temp);
                if ((temp == 0)) {
                    q.addLast(connected_node);
                }
            }
        }
 
        // If indegree of any vertices is not 0,
        // return false.
 
        for (int itr : indegree.keySet()) {
            if (indegree.get(itr) != 0)
                return false;
        }
 
        return true;
    }
   
    // Driver Code
    public static void main(String[] args)
    {
        ArrayList > arr
            = new ArrayList >();
        arr.add(
            new ArrayList(Arrays.asList(1, 2)));
        arr.add(
            new ArrayList(Arrays.asList(1, 3)));
 
        int N = arr.size(), M = arr.get(0).size();
        if (shortestSuperSeq(arr, N, M))
            System.out.println("True");
        else
            System.out.println("False");
    }
}
 
// This code is contributed by Palak Gupta


Python3
# Python code for the above approach
 
# Function to check unique
# shortest common supersequence
def shortestSuperSeq(arr, N, M):
 
    # Initializing map to store
    # edges and indegree of vertices
    adj = {}
    indegree = {}
     
    # Initializing all keys of map
    # with values of sequences in arr
    for i in range(N):
        for j in range(M):
            node = arr[i][j];
            adj[node] =  []
            indegree[node] = 0
         
    # For every sequence in arr
    # calculate indegree and edges.
    for seq in arr:
        for i in range(1, M):
            adj[seq[i - 1]].append(seq[i]);
            indegree[seq[i]] += 1
         
    # Vector to store
    # topologically sorted order.
    res = [];
    q = [];
 
    # Push vertices with 0 indegree in queue
    for k in indegree.keys():
        if (indegree[k] == 0):
            q.append(k);
         
 
    while (len(q) != 0):
        size = len(q)
 
        # If size of q > 1, this means
        # more than one choices,
        # so no unique common supersequence
        # can be formed.
        if (size != 1):
            return False;
 
        node = q.pop(0);
 
        # Add node to topological sort order
        res.append(node);
 
        # Decrement indegree of all
        # the vertices connected to node
        for i in range(len(adj[node])):
            connected_node = adj[node][i];
 
            # Push vertices with 0 indegree
            # to queue
            indegree[connected_node] -= 1
            if (indegree[connected_node] == 0):
                q.append(connected_node);
             
    # If indegree of any vertices is not 0,
    # return false.
    for itr in indegree.keys():
        if (itr != 0):
            return False;
     
    return True;
 
# Driver Code
arr = [[1, 2], [1, 3]];
N = len(arr)
M = len(arr[0])
if (shortestSuperSeq(arr, N, M)):
    print("True");
else:
    print("False")
 
# This code is contributed by Saurabh Jaiswal


Javascript



输出
False

时间复杂度: O(N * M)
辅助空间: O(N * M)