给定一个字符串数组arr [] ,任务是从该数组中打印字符串,这些字符串不是同一数组中任何其他字符串的前缀。
例子:
Input: arr[] = {“apple”, “app”, “there”, “the”, “like”}
Output:
apple
like
there
Here “app” is a prefix of “apple”
Hence, it is not printed and
“the” is a prefix of “there”
Input: arr[] = {“a”, “aa”, “aaa”, “aaaa”}
Output:
aaaa
天真的方法:对于数组的每个字符串,我们检查它是否为其他任何字符串的前缀。如果是,则不显示它。
高效的方法:我们从数组中一个接一个地挑选字符串,并将其插入到Trie中。然后有两种情况插入字符串:
- 在插入时,如果发现所选择的字符串是已插入字符串的前缀,则我们不会将此字符串插入到Trie中。
- 如果先将前缀插入到Trie中,然后再发现该字符串是某个单词的前缀,则对于该特定节点,我们只需将isEndOfWord = false即可。
构造Trie之后,我们遍历它并显示Trie中的所有单词。
下面是上述方法的实现:
CPP
// C++ implementation of the approach
#include
using namespace std;
const int ALPHABET_SIZE = 26;
// Trie node
struct TrieNode {
struct TrieNode* children[ALPHABET_SIZE];
// isEndOfWord is true if the node represents
// end of a word
bool isEndOfWord;
};
// Returns new trie node (initialized to NULLs)
struct TrieNode* getNode(void)
{
struct TrieNode* pNode = new TrieNode;
pNode->isEndOfWord = false;
for (int i = 0; i < ALPHABET_SIZE; i++)
pNode->children[i] = NULL;
return pNode;
}
// Function to insert a string into trie
void insert(struct TrieNode* root, string key)
{
struct TrieNode* pCrawl = root;
for (int i = 0; i < key.length(); i++) {
int index = key[i] - 'a';
if (!pCrawl->children[index])
pCrawl->children[index] = getNode();
// While inerting a word make
// each isEndOfWord as false
pCrawl->isEndOfWord = false;
pCrawl = pCrawl->children[index];
}
int i;
// Check if this word is prefix of
// some already inserted word
// If it is then don't insert this word
for (i = 0; i < 26; i++) {
if (pCrawl->children[i]) {
break;
}
}
// If present word is not prefix of
// any other word then insert it
if (i == 26) {
pCrawl->isEndOfWord = true;
}
}
// Function to display words in Trie
void display(struct TrieNode* root, char str[], int level)
{
// If node is leaf node, it indicates end
// of string, so a null character is added
// and string is displayed
if (root->isEndOfWord) {
str[level] = '\0';
cout << str << endl;
}
int i;
for (i = 0; i < ALPHABET_SIZE; i++) {
// If NON NULL child is found
// add parent key to str and
// call the display function recursively
// for child node
if (root->children[i]) {
str[level] = i + 'a';
display(root->children[i], str, level + 1);
}
}
}
// Driver code
int main()
{
string keys[] = { "apple", "app", "there",
"the", "like" };
int n = sizeof(keys) / sizeof(string);
struct TrieNode* root = getNode();
// Construct trie
for (int i = 0; i < n; i++)
insert(root, keys[i]);
char str[100];
display(root, str, 0);
return 0;
}
Java
// Java implementation of the approach
import java.util.Arrays;
class GFG
{
static final int ALPHABET_SIZE = 26;
// Trie node
static class TrieNode
{
TrieNode[] children;
// isEndOfWord is true if the node represents
// end of a word
boolean isEndOfWord;
TrieNode()
{
this.children = new TrieNode[ALPHABET_SIZE];
}
}
// Returns new trie node (initialized to NULLs)
static TrieNode getNode()
{
TrieNode pNode = new TrieNode();
pNode.isEndOfWord = false;
Arrays.fill(pNode.children, null);
return pNode;
}
// Function to insert a String into trie
static void insert(TrieNode root, String key)
{
TrieNode pCrawl = root;
for (int i = 0; i < key.length(); i++)
{
int index = key.charAt(i) - 'a';
if (pCrawl.children[index] == null)
pCrawl.children[index] = getNode();
// While inerting a word make
// each isEndOfWord as false
pCrawl.isEndOfWord = false;
pCrawl = pCrawl.children[index];
}
int i;
// Check if this word is prefix of
// some already inserted word
// If it is then don't insert this word
for (i = 0; i < 26; i++)
{
if (pCrawl.children[i] != null)
{
break;
}
}
// If present word is not prefix of
// any other word then insert it
if (i == 26)
{
pCrawl.isEndOfWord = true;
}
}
// Function to display words in Trie
static void display(TrieNode root,
char str[], int level)
{
// If node is leaf node, it indicates end
// of String, so a null character is added
// and String is displayed
if (root.isEndOfWord)
{
str[level] = '\0';
System.out.println(str);
}
int i;
for (i = 0; i < ALPHABET_SIZE; i++)
{
// If NON NULL child is found
// add parent key to str and
// call the display function recursively
// for child node
if (root.children[i] != null)
{
str[level] = (char) (i + 'a');
display(root.children[i], str, level + 1);
}
}
}
// Driver code
public static void main(String[] args)
{
String keys[] = { "apple", "app", "there", "the", "like" };
int n = keys.length;
TrieNode root = getNode();
// Conclass trie
for (int i = 0; i < n; i++)
insert(root, keys[i]);
char[] str = new char[100];
display(root, str, 0);
}
}
// This code is contributed by sanjeev2552
输出:
apple
like
there