执行等效操作后形成的不同字符串组的计数
给定一个包含N个由小写字母组成的字符串的数组arr[] ,任务是找出执行等效操作后形成的不同字符串组的数量。
Two strings are said to be equivalent if there exists the same character in both the strings and if there exists another string that is equivalent to one of the strings in the group of equivalent string then that string is also equivalent to that group.
例子:
Input: arr[] = {“a”, “b”, “ab”, “d”}
Output: 2
Explanation:
As strings “b” and “ab” have ‘b’ as the same character, they are equivalent also “ab” and the string”a” have ‘a’ as the same character, so the strings “a”, “b”, “ab” are equivalent and “d” is another string.
Therefore, the count of distinct group of strings formed is 2.
Input: arr[] = {“ab”, “bc”, “abc”}
Output: 1
方法:给定的问题可以使用不相交集并集来解决,思路是遍历字符串,将当前字符串的所有字符标记为真,并对当前字符串的第一个字符与字符'a进行并集运算' ,并计算父向量中不同的父节点数量并存储。请按照以下步骤解决问题:
- 初始化向量parent(27)、rank(27, 0)、total(26, false)和current(26, false) 。
- 初始化一个变量,例如distCount为0存储不同字符串的计数。
- 使用变量i遍历范围[0, 27)并将parent[i]的值设置为i 。
- 使用变量i迭代范围[0, N)并执行以下步骤:
- 使用变量j迭代范围[0, 26)并将current[j]设置为false 。
- 使用变量ch遍历字符arr[i]的字符串并将current[ch – 'a']设置为true 。
- 使用变量j在范围[0, 26)上进行迭代,如果current[j]为 true,则将total[j]设置为true并调用函数Union(parent, rank, arr[i][0] – 'a ', j) 。
- 使用变量i遍历范围[0, 26)并检查total[i]是否为真, Find(parent, i)是否为I如果为真,则将 distCount的值增加1 。
- 最后,打印distCount的值。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to perform the find operation
// to find the parent of a disjoint set
int Find(vector& parent, int a)
{
return parent[a]
= (parent[a] == a ? a : Find(parent, parent[a]));
}
// Function to perform union operation
// of disjoint set union
void Union(vector& parent,
vector& rank, int a,
int b)
{
// Find the parent of node a and b
a = Find(parent, a);
b = Find(parent, b);
// Update the rank
if (rank[a] == rank[b])
rank[a]++;
if (rank[a] > rank[b])
parent[b] = a;
else
parent[a] = b;
}
// Function to find the number of distinct
// strings after performing the
// given operations
void numOfDistinctStrings(string arr[],
int N)
{
// Stores the parent elements
// of the sets
vector parent(27);
// Stores the rank of the sets
vector rank(27, 0);
for (int j = 0; j < 27; j++) {
// Update parent[i] to i
parent[j] = j;
}
// Stores the total characters
// traversed through the strings
vector total(26, false);
// Stores the current characters
// traversed through a string
vector current(26, false);
for (int i = 0; i < N; i++) {
for (int j = 0; j < 26; j++) {
// Update current[i] to false
current[j] = false;
}
for (char ch : arr[i]) {
// Update current[ch - 'a'] to true
current[ch - 'a'] = true;
}
for (int j = 0; j < 26; j++) {
// Check if current[j] is true
if (current[j]) {
// Update total[j] to true
total[j] = true;
// Add arr[i][0] - 'a' and
// j elements to same set
Union(parent, rank,
arr[i][0] - 'a', j);
}
}
}
// Stores the count of distinct strings
int distCount = 0;
for (int i = 0; i < 26; i++) {
// Check total[i] is true and
// parent of i is i only
if (total[i] && Find(parent, i) == i) {
// Increment the value of
// distCount by 1
distCount++;
}
}
// Print the value of distCount
cout << distCount << endl;
}
// Driver Code
int main()
{
string arr[] = { "a", "ab", "b", "d" };
int N = sizeof(arr) / sizeof(arr[0]);
numOfDistinctStrings(arr, N);
return 0;
}
Python3
# python program for the above approach
# Function to perform the find operation
# to find the parent of a disjoint set
def Find(parent, a):
if parent[a] == a:
parent[a] = a
return parent[a]
else:
parent[a] = Find(parent, parent[a])
return parent[a]
# Function to perform union operation
# of disjoint set union
def Union(parent, rank, a, b):
# Find the parent of node a and b
a = Find(parent, a)
b = Find(parent, b)
# Update the rank
if (rank[a] == rank[b]):
rank[a] += 1
if (rank[a] > rank[b]):
parent[b] = a
else:
parent[a] = b
# Function to find the number of distinct
# strings after performing the
# given operations
def numOfDistinctStrings(arr, N):
# Stores the parent elements
# of the sets
parent = [0 for _ in range(27)]
# Stores the rank of the sets
rank = [0 for _ in range(27)]
for j in range(0, 27):
# Update parent[i] to i
parent[j] = j
# Stores the total characters
# traversed through the strings
total = [False for _ in range(26)]
# Stores the current characters
# traversed through a string
current = [False for _ in range(26)]
for i in range(0, N):
for j in range(0, 26):
# Update current[i] to false
current[j] = False
for ch in arr[i]:
# Update current[ch - 'a'] to true
current[ord(ch) - ord('a')] = True
for j in range(0, 26):
# Check if current[j] is true
if (current[j]):
# Update total[j] to true
total[j] = True
# Add arr[i][0] - 'a' and
# j elements to same set
Union(parent, rank, ord(arr[i][0]) - ord('a'), j)
# Stores the count of distinct strings
distCount = 0
for i in range(0, 26):
# Check total[i] is true and
# parent of i is i only
if (total[i] and Find(parent, i) == i):
# Increment the value of
# distCount by 1
distCount += 1
# Print the value of distCount
print(distCount)
# Driver Code
if __name__ == "__main__":
arr = ["a", "ab", "b", "d"]
N = len(arr)
numOfDistinctStrings(arr, N)
# This code is contributed by rakeshsahni
C#
// C# program for the above approach
using System;
class GFG {
// Function to perform the find operation
// to find the parent of a disjoint set
static int Find(int[] parent, int a)
{
return parent[a]
= (parent[a] == a ? a
: Find(parent, parent[a]));
}
// Function to perform union operation
// of disjoint set union
static void Union(int[] parent, int[] rank, int a,
int b)
{
// Find the parent of node a and b
a = Find(parent, a);
b = Find(parent, b);
// Update the rank
if (rank[a] == rank[b])
rank[a]++;
if (rank[a] > rank[b])
parent[b] = a;
else
parent[a] = b;
}
// Function to find the number of distinct
// strings after performing the
// given operations
static void numOfDistinctStrings(string[] arr, int N)
{
// Stores the parent elements
// of the sets
int[] parent = new int[(27)];
// Stores the rank of the sets
int[] rank = new int[(27)];
for (int j = 0; j < 27; j++) {
// Update parent[i] to i
parent[j] = j;
}
// Stores the total characters
// traversed through the strings
bool[] total = new bool[26];
// Stores the current characters
// traversed through a string
bool[] current = new bool[26];
for (int i = 0; i < N; i++) {
for (int j = 0; j < 26; j++) {
// Update current[i] to false
current[j] = false;
}
foreach(char ch in arr[i])
{
// Update current[ch - 'a'] to true
current[ch - 'a'] = true;
}
for (int j = 0; j < 26; j++) {
// Check if current[j] is true
if (current[j]) {
// Update total[j] to true
total[j] = true;
// Add arr[i][0] - 'a' and
// j elements to same set
Union(parent, rank, arr[i][0] - 'a', j);
}
}
}
// Stores the count of distinct strings
int distCount = 0;
for (int i = 0; i < 26; i++) {
// Check total[i] is true and
// parent of i is i only
if (total[i] && Find(parent, i) == i) {
// Increment the value of
// distCount by 1
distCount++;
}
}
// Print the value of distCount
Console.WriteLine(distCount);
}
// Driver Code
public static void Main()
{
string[] arr = { "a", "ab", "b", "d" };
int N = arr.Length;
numOfDistinctStrings(arr, N);
}
}
// This code is contributed by ukasp.
2
时间复杂度: O(N*log N)
辅助空间: O(N)