面试官问到:给定一个字符串,请处理成一个没有重复字符的字符串
当时想到的是一个简单但性能普通的方法,这个方法普通人都能想得到
吃完饭后我回到寝室,分析不能每次判断有没有重复都去遍历已遍历过的每个字符
为此,想到了数组的直接存取性质,于是豁然开朗:
算法差不多是这样的:
假设char str[]="bavdfegsgah$ #@";
那么先建立一个字典映射函数//其实相当于创建了索引
int indexStr(char c)
{
if(c=='a') return 0;
else if(c=='b') return 1;
...
else return -1;
}
//main
int[] s1=new int[indexStrCount];//indexStrCount为字典中字符的个数
int[] s2=new int[indexStrCount];
int i,j;
for (i=0;i<strLength;i++)//strLength为str中字符的个数
{
s1[i]=0;
}
for (i=0,j=0;i<strLength;i++)
{
if(s1[indexStr(str[i])]==0)//判断该字符是否重复(存在时s1[i]=1)过
{
s1[i]=1;
s2[j++]=str[i];
if(j>=indexStrCount)break;
}
}
//最后s2就是不重复的字符串,当然还可以考虑得更全面,上面的算法时间复杂度是T(n);
//一般人的第一次想法是判断当前字符有没有在已遍历的数组里面(此时要遍历该数组),这样时间复杂度就增大为T(n^2);
昨晚睡觉前又想了下,indexStr()函数似乎也类似遍历,看来得使用ASCII表和汉字编码表,将字符和整数进行映射,比如字符'a'对应65,这样可以直接从字符找到数组下标,就可以用到数组的直接存取功能了