給定 n (≤ 10000) 個電話號碼(≤ 10 位數字),判斷是否存在某號碼是另一號碼的前綴。存在輸出 NO,否則 YES。
tag++tag > 0,說明有號碼是當前的前綴 → NOstruct TrieNode { int tag, next[10]; } trie[100005];
int tot = 0;
char phones[10005][11];
void insert(char* s) {
int u = 0;
for (int i = 0; s[i]; ++i) {
int c = s[i] - '0';
if (!trie[u].next[c]) trie[u].next[c] = ++tot;
u = trie[u].next[c];
}
trie[u].tag++;
}
bool judge(char* s) {
int u = 0, len = strlen(s);
for (int i = 0; i < len - 1; ++i) { // 只檢查到倒數第二位
int c = s[i] - '0';
u = trie[u].next[c];
if (trie[u].tag) return false; // 有號碼在此結尾,是前綴
}
return true;
}
int main() {
int T; scanf("%d", &T);
while (T--) {
// 清理 trie
for (int i = 0; i <= tot; ++i) {
memset(trie[i].next, 0, sizeof(trie[i].next));
trie[i].tag = 0;
}
tot = 0;
int n; scanf("%d", &n);
for (int i = 1; i <= n; ++i) {
scanf("%s", phones[i]);
insert(phones[i]);
}
bool ok = true;
for (int i = 1; i <= n; ++i) {
if (!judge(phones[i])) { ok = false; break; }
}
puts(ok ? "YES" : "NO");
}
return 0;
}
將號碼排序,只需檢查相鄰兩個是否有前綴關係。時間 O(n log n × L),代碼更短。