📌  相关文章
📜  打印给定数组中存在的所有唯一字符串

📅  最后修改于: 2021-04-17 12:42:33             🧑  作者: Mango

给定一个字符串数组arr [] ,任务是打印给定数组中存在的所有唯一字符串。

例子:

天真的方法:解决此问题的最简单方法是遍历遇到的每个字符串的数组,检查该字符串出现在其余数组中。打印那些仅在数组中出现一次的字符串。
时间复杂度: 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)