检查给定的数组是否有唯一的最短公共超序列
给定一个大小为N*M的二维数组arr[][] ,它表示N个数组,每个数组的大小为M 。任务是检查所有这些数组是否具有唯一的公共超序列。
例子:
Input: N = 2, M = 2, arr[][] = { { 1, 2 }, {1, 3 } }
Output: False
Explanation: There are two possible supersequence: {1, 3, 2 } and {1, 2, 3}.
Input: N = 3, M = 2, arr[][] = { { 1, 2 }, {1, 3}, {2, 3 } }
Output: True
Explanation: { 1, 2, 3 } is the only shortest common supersequence of {1, 2}, {1, 3} and {2, 3}.
方法:思想是使用拓扑排序,按照下面提到的步骤解决问题:
- 用有向图表示“ 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)