Phone List
问题分析:
我的思路就是直接使用字典树,在每个单词的结尾所对应的位置做一个标记,每次在向字典树中更新数据的时候,同时进行判断:
如果当前单词没有结束但是已经遇到了之前出现过的一个单词的结尾标记,则说明其存在前缀,结果输出NO。只有每个单词都不存在前缀时输出YES。
字典树的具体实现有好几种方式:
1.数组来实现
2.以指针实现
我采用的是用指针来实现,但是在具体的过程中,我一开始的动态空间写法提交超时了,真的很迷惑,我找了好几个平台,提交却通过了,后来发现只有在POJ提交才会报TLE,可能是POJ的数据比较强吧。
后来找了一些资料,参考了别人的写法,发现别人虽然也是采用指针来实现,但并没有使用动态空间,而是一开始直接申请了一片空间,然后后续的操作直接在这片空间里面进行(这片空间大小的确定有点难搞,大了小了都不行,要卡一下)
静态空间的写法跟动态空间的区别在于空间的处理:
动态空间需要申请空间,申请之后要先对空间进行一个初始化,操作结束后还要对空间进行一个释放,如果不进行释放,提交后空间会出问题。
超时的原因可能就是多次的申请内存空间跟释放。
代码:
//静态空间指针写法
#include<iostream>
#include<cstring>
#include<stdlib.h>
#include<stdio.h>
using namespace std;
int t,n;
char tmp[20];
struct node {
int flag;
node* next[10];
};
node mem[60005];
int cnt;
int snt;
node *root;
node* creat(){
node *a=&(mem[snt++]);
a->flag=0;
for(int i=0;i<10;i++)a->next[i]=NULL;
return a;
}
void add(node* root,char a[]){
if(cnt==1)return;
int ss=0;
node *p=root,*pp;
for(int i=0;a[i];i++){
int x=a[i]-'0';
if(p->next[x]==NULL){
ss=1;
pp=creat();
p->next[x]=pp;
p=pp;
}
else{
p=p->next[x];
if(p->flag==1)cnt=1;
}
}
if(!ss)cnt=1;
p->flag=1;
}
int main(){
cin>>t;
while(t--){
cin>>n;
memset(mem,0,sizeof(mem));
cnt=snt=0;
root=creat();
for(int i=0;i<n;i++){
scanf("%s",tmp);
add(root,tmp);
}
if(cnt==0)cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
}
//动态空间写法
#include<iostream>
#include<cstring>
#include<stdlib.h>
#include<stdio.h>
using namespace std;
int t,n;
char tmp[20];
struct node {
int flag;
node* next[10];
};
int cnt;
node *root;
node * creat(){
node *a=(node*)malloc(sizeof(node));
a->flag=0;
for(int i=0;i<10;i++)a->next[i]=NULL;
return a;
}
void add(node* root,char a[]){
if(cnt==1)return;
int ss=0;
node *p=root,*pp;
for(int i=0;a[i];i++){
int x=a[i]-'0';
if(p->next[x]==NULL){
ss=1;
pp=creat();
p->next[x]=pp;
p=pp;
}
else{
p=p->next[x];
if(p->flag==1)cnt=1;
}
}
if(!ss)cnt=1;
p->flag=1;
}
void del(node *p){
int i;
for(i=0;i<10;i++)
if(p->next[i]!=NULL)del(p->next[i]);
free(p);
}
int main(){
scanf("%d",&t);
while(t--){
scanf("%d",&n);
root=creat();
cnt=0;
for(int i=0;i<n;i++){
scanf("%s",tmp);
add(root,tmp);
}
if(cnt==0)cout<<"YES"<<endl;
else cout<<"NO"<<endl;
del(root);
}
}