给定一个字符串数组arr [] ,任务是打印给定数组中存在的所有唯一字符串。
例子:
Input: arr[] = { “geeks”, “geek”, “ab”, “geek” “code”, “karega” }
Output: geeks ab code karega
Explanation:
The frequency of the string “geeks” is 1.
The frequency of the string “geek” is 2.
The frequency of the string “ab” is 1.
The frequency of the string “code” is 1.
The frequency of the string “karega” is 1.
Therefore, the required output is “geeks ab code karega”
Input: arr[] = { “abcde”, “abcd”, “abcd”, “co” “”, “code” }
Output: abcde co code
天真的方法:解决此问题的最简单方法是遍历遇到的每个字符串的数组,检查该字符串出现在其余数组中。打印那些仅在数组中出现一次的字符串。
时间复杂度: O(N 2 * M),其中M是字符串的最大长度
辅助空间: O(1)
高效方法:可以使用Trie优化上述方法。这个想法是遍历数组,并针对数组中的每个第i个字符串,检查Trie中是否存在arr [i] 。如果发现为真,则将arr [i]标记为重复数组元素。否则,将arr [i]标记为唯一数组元素,然后将arr [i]插入特里。请按照以下步骤解决问题:
- 初始化一个数组,例如isUniq [] ,以检查数组元素是否唯一。
- 创建具有根节点特里,说根,每个本字符串的字符存储在给定阵列英寸
- 使用变量i遍历数组,并对于每个第i个元素,检查Trie中是否存在arr [i] 。如果发现为true,则将isUniq [i]更新为false。
- 否则,将isUniq [i]更新为true,然后将arr [i]插入Trie。
- 最后,使用变量i遍历isUniq []数组,对于每个第i个元素,检查isUniq [i]是否为true。如果发现为真,则打印arr [i] 。
下面是上述方法的实现:
C++
// C++ program to implement
// the above approach
#include
using namespace std;
// Structure of
// a Trie node
struct TrieNode {
// Stores index
// of string
int idx;
// Check if a character is
// present in the string or not
TrieNode* child[26];
// Initialize a TrieNode
TrieNode()
{
// Idx = -1: String is not
// present in TrieNode
idx = -1;
// Initialize all child nodes
// of a TrieNode to NULL
for (int i = 0; i < 26; i++) {
// Update child[i]
child[i] = NULL;
}
}
};
// Function to insert a string into Trie
void Insert(TrieNode* root,
string str, int i)
{
// Stores length of the string
int N = str.length();
// Traverse the string str
for (int i = 0; i < N; i++) {
// If str[i] not present in
// a Trie at current index
if (!root->child[str[i] - 'a']) {
// Create a new node of Trie.
root->child[str[i] - 'a']
= new TrieNode();
}
// Update root
root = root->child[str[i] - 'a'];
}
// Store index of str
// in the TrieNode
root->idx = i;
}
// Function to check if string str present
// in the Trie or not
int SearchString(TrieNode* root, string str)
{
// Stores length of
// the string
int N = str.length();
// Traverse the string
for (int i = 0; i < N; i++) {
// If a character not present
// in Trie at current index
if (!root->child[str[i] - 'a']) {
// Return str as
// unique string
return -1;
}
// Update root
root
= root->child[str[i] - 'a'];
}
// Return index of str
return root->idx;
}
// Utility function to find the unique
// string in array of strings
void UtilUniqStr(vector& arr, int N)
{
// Stores root node of the Trie
TrieNode* root = new TrieNode();
// isUniq[i]: Check if i-th string
// is unique or not
bool isUniq[N];
// Initialize isUniq[] to false
memset(isUniq, false, sizeof(isUniq));
// Insert arr[0] into the Trie
Insert(root, arr[0], 0);
// Mark arr[0] as unique string
isUniq[0] = true;
// Traverse the given array
for (int i = 1; i < N; i++) {
// Stores previous 1st index
// of arr[i] in the array
int idx = SearchString(root,
arr[i]);
// If arr[i] not present
// in the Trie
if (idx == -1) {
// Mark i-th string
// as unique string
isUniq[i] = true;
// Insert arr[i] into Trie
Insert(root, arr[i], i);
}
// If arr[i] already present
// in the Trie
else {
// Mark i-th string as
// duplicate string in Trie
isUniq[idx] = false;
}
}
// Traverse the array
for (int i = 0; i < N; i++) {
// If i-th string is unique,
// then print the string
if (isUniq[i]) {
cout << arr[i] << " ";
}
}
}
// Driver Code
int main()
{
vector arr = { "geeks", "for",
"geek", "ab", "geek",
"for", "code", "karega" };
int N = arr.size();
UtilUniqStr(arr, N);
return 0;
}
Java
// Java program to implement
// the above approach
import java.util.*;
class GFG
{
// Structure of
// a Trie node
static class TrieNode {
// Stores index
// of String
int idx;
// Check if a character is
// present in the String or not
TrieNode []child = new TrieNode[26];
// Initialize a TrieNode
TrieNode()
{
// Idx = -1: String is not
// present in TrieNode
idx = -1;
// Initialize all child nodes
// of a TrieNode to null
for (int i = 0; i < 26; i++) {
// Update child[i]
child[i] = null;
}
}
};
// Function to insert a String into Trie
static void Insert(TrieNode root,
String str, int i)
{
// Stores length of the String
int N = str.length();
// Traverse the String str
for (int j = 0; j < N; j++) {
// If str[i] not present in
// a Trie at current index
if (root.child[str.charAt(j) - 'a']==null) {
// Create a new node of Trie.
root.child[str.charAt(j) - 'a']
= new TrieNode();
}
// Update root
root = root.child[str.charAt(j) - 'a'];
}
// Store index of str
// in the TrieNode
root.idx = i;
}
// Function to check if String str present
// in the Trie or not
static int SearchString(TrieNode root, String str)
{
// Stores length of
// the String
int N = str.length();
// Traverse the String
for (int i = 0; i < N; i++) {
// If a character not present
// in Trie at current index
if (root.child[str.charAt(i) - 'a'] == null) {
// Return str as
// unique String
return -1;
}
// Update root
root
= root.child[str.charAt(i) - 'a'];
}
// Return index of str
return root.idx;
}
// Utility function to find the unique
// String in array of Strings
static void UtilUniqStr(String[] arr, int N)
{
// Stores root node of the Trie
TrieNode root = new TrieNode();
// isUniq[i]: Check if i-th String
// is unique or not
boolean []isUniq = new boolean[N];
// Insert arr[0] into the Trie
Insert(root, arr[0], 0);
// Mark arr[0] as unique String
isUniq[0] = true;
// Traverse the given array
for (int i = 1; i < N; i++) {
// Stores previous 1st index
// of arr[i] in the array
int idx = SearchString(root,
arr[i]);
// If arr[i] not present
// in the Trie
if (idx == -1) {
// Mark i-th String
// as unique String
isUniq[i] = true;
// Insert arr[i] into Trie
Insert(root, arr[i], i);
}
// If arr[i] already present
// in the Trie
else {
// Mark i-th String as
// duplicate String in Trie
isUniq[idx] = false;
}
}
// Traverse the array
for (int i = 0; i < N; i++) {
// If i-th String is unique,
// then print the String
if (isUniq[i]) {
System.out.print(arr[i]+ " ");
}
}
}
// Driver Code
public static void main(String[] args)
{
String[] arr = { "geeks", "for",
"geek", "ab", "geek",
"for", "code", "karega" };
int N = arr.length;
UtilUniqStr(arr, N);
}
}
// This code is contributed by 29AjayKumar
Python3
# Python3 program to implement
# the above approach
root = None
# Structure of
# a Trie node
class TrieNode:
# Stores index
# of string
def __init__(self):
self.idx = -1
self.child = [None]*26
# Function to insert a string into Trie
def Insert(str, i):
global root
# Stores length of the string
N = len(str)
root1 = root
# Traverse the string str
for i in range(N):
# If str[i] not present in
# a Trie at current index
if (not root1.child[ord(str[i]) - ord('a')]):
# Create a new node of Trie.
root1.child[ord(str[i]) - ord('a')] = TrieNode()
# Update root
root1 = root1.child[ord(str[i]) - ord('a')]
# Store index of str
# in the TrieNode
root1.idx = i
return root1
# Function to check if string str present
# in the Trie or not
def SearchString(str):
global root
root1 = root
# Stores length of
# the
N = len(str)
# Traverse the
for i in range(N):
# If a character not present
# in Trie at current index
if (not root1.child[ord(str[i]) - ord('a')]):
# Return str as
# unique
return -1
# Update root
root1 = root1.child[ord(str[i]) - ord('a')]
# Return index of str
return root1.idx
# Utility function to find the unique
# string in array of strings
def UtilUniqStr(arr, N):
global root
# Stores root node of the Trie
root = TrieNode()
d = {}
for i in arr:
d[i] = d.get(i, 0) + 1
# isUniq[i]: Check if i-th string
# is unique or not
isUniq = [False] * N
# Initialize isUniq[] to false
# memset(isUniq, false, sizeof(isUniq));
# Insert arr[0] into the Trie
Insert(arr[0], 0)
# Mark arr[0] as unique string
isUniq[0] = True
# print(root.child[6].child)
# Traverse the given array
for i in range(1, N):
# Stores previous 1st index
# of arr[i] in the array
idx = SearchString(arr[i])
# If arr[i] not present
# in the Trie
if (idx == -1 and d[arr[i]] == 1):
# Mark i-th string
# as unique string
isUniq[i] = True
# Insert arr[i] into Trie
Insert(arr[i], i)
# If arr[i] already present
# in the Trie
else:
# Mark i-th string as
# duplicate string in Trie
isUniq[idx] = False
# Traverse the array
for i in range(N):
# If i-th string is unique,
# then print the string
if (isUniq[i]):
print(arr[i], end = " ")
# Driver Code
if __name__ == '__main__':
arr = ["geeks", "for","geek", "ab", "geek","for", "code", "karega"]
N = len(arr)
UtilUniqStr(arr, N)
# This code is contributed by mohit kumar 29
C#
// C# program to implement
// the above approach
using System;
class GFG
{
// Structure of
// a Trie node
class TrieNode {
// Stores index
// of String
public int idx;
// Check if a character is
// present in the String or not
public TrieNode []child = new TrieNode[26];
// Initialize a TrieNode
public TrieNode()
{
// Idx = -1: String is not
// present in TrieNode
idx = -1;
// Initialize all child nodes
// of a TrieNode to null
for (int i = 0; i < 26; i++) {
// Update child[i]
child[i] = null;
}
}
};
// Function to insert a String into Trie
static void Insert(TrieNode root,
String str, int i)
{
// Stores length of the String
int N = str.Length;
// Traverse the String str
for (int j = 0; j < N; j++) {
// If str[i] not present in
// a Trie at current index
if (root.child[str[j] - 'a'] == null) {
// Create a new node of Trie.
root.child[str[j] - 'a']
= new TrieNode();
}
// Update root
root = root.child[str[j] - 'a'];
}
// Store index of str
// in the TrieNode
root.idx = i;
}
// Function to check if String str present
// in the Trie or not
static int SearchString(TrieNode root, String str)
{
// Stores length of
// the String
int N = str.Length;
// Traverse the String
for (int i = 0; i < N; i++) {
// If a character not present
// in Trie at current index
if (root.child[str[i] - 'a'] == null) {
// Return str as
// unique String
return -1;
}
// Update root
root
= root.child[str[i] - 'a'];
}
// Return index of str
return root.idx;
}
// Utility function to find the unique
// String in array of Strings
static void UtilUniqStr(String[] arr, int N)
{
// Stores root node of the Trie
TrieNode root = new TrieNode();
// isUniq[i]: Check if i-th String
// is unique or not
bool []isUniq = new bool[N];
// Insert arr[0] into the Trie
Insert(root, arr[0], 0);
// Mark arr[0] as unique String
isUniq[0] = true;
// Traverse the given array
for (int i = 1; i < N; i++) {
// Stores previous 1st index
// of arr[i] in the array
int idx = SearchString(root,
arr[i]);
// If arr[i] not present
// in the Trie
if (idx == -1) {
// Mark i-th String
// as unique String
isUniq[i] = true;
// Insert arr[i] into Trie
Insert(root, arr[i], i);
}
// If arr[i] already present
// in the Trie
else {
// Mark i-th String as
// duplicate String in Trie
isUniq[idx] = false;
}
}
// Traverse the array
for (int i = 0; i < N; i++) {
// If i-th String is unique,
// then print the String
if (isUniq[i]) {
Console.Write(arr[i] + " ");
}
}
}
// Driver Code
public static void Main(String[] args)
{
String[] arr = { "geeks", "for",
"geek", "ab", "geek",
"for", "code", "karega" };
int N = arr.Length;
UtilUniqStr(arr, N);
}
}
// This code is contributed by 29AjayKumar
geeks ab code karega
时间复杂度: O(N * M),其中M是字符串的最大长度
辅助空间: O(N * 26)