给定的一组字符串中最长的公共前缀(使用trie)


Question

在给定的一组字符串中查找最长公用前缀(LCP)
keys = [“codable”, “code”, “coder”, “coding”]
最长公用前缀 “cod”
输出:The longest common prefix is cod



Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
public class A071 {

static final int ALPHABET_SIZE = 26;

static class TrieNode {
// 每个节点有26个子节点,代表26个英文字母
TrieNode[] children = new TrieNode[ALPHABET_SIZE];
boolean isLeaf;// 是否是叶子节点

public TrieNode() {
isLeaf = false;
for (int i = 0; i < ALPHABET_SIZE; i++)
children[i] = null;
}
}

static TrieNode root;
static int indexs;

// 将一个字符串插入到Trie中,一次插入字符串每个字符
// 如果该索引位置为空则开辟一个空间,否则继续向下添加
static void insert(String key) {
int length = key.length();
int index;

TrieNode pCrawl = root;

for (int level = 0; level < length; level++) {
index = key.charAt(level) - 'a';
if (pCrawl.children[index] == null)
pCrawl.children[index] = new TrieNode();

pCrawl = pCrawl.children[index];
}

// 将最后的结点标记为叶子节点
pCrawl.isLeaf = true;
}

// 传入一个节点,返回其孩子个数
static int countChildren(TrieNode node) {
int count = 0;
for (int i = 0; i < ALPHABET_SIZE; i++) {
if (node.children[i] != null) {
count++;
indexs = i;
}
}
return (count);
}

// 返回最长公共前缀
static String walkTrie() {
TrieNode pCrawl = root;
indexs = 0;
String prefix = "";
// 当遍历到的节点只有一个孩子且不是叶子节点,则加入到公共前缀中
while (countChildren(pCrawl) == 1 && pCrawl.isLeaf == false) {
pCrawl = pCrawl.children[indexs];// 指向其唯一的孩子节点
prefix += (char) ('a' + indexs);// 将该节点加入到公共前缀中
}
return prefix;
}

// 将字符串数组加入到Trie中
static void constructTrie(String arr[], int n) {
for (int i = 0; i < n; i++)
insert(arr[i]);
return;
}

// 返回最长公共前缀
static String commonPrefix(String arr[], int n) {
root = new TrieNode();
constructTrie(arr, n);
return walkTrie();
}

public static void main(String args[]) {

String arr[] = { "codable", "code", "coder", "coding" };
int n = arr.length;

String ans = commonPrefix(arr, n);

if (ans.length() != 0)
System.out.println("The longest common prefix is " + ans);
else
System.out.println("There is no common prefix");

}
}