题目描述:
请实现一个算法,确定一个字符串的所有字符是否全都不同。这里我们要求不允许使用额外的存储结构。给定一个stringiniString,请返回一个bool值,True代表所有字符全都不同,False代表存在相同的字符。保证字符串中的字符为ASCII字符。字符串的长度小于等于3000。
思路一:(时间复杂度为O(N*N))
看到这道题目第一想法就是将每个字符与其他字符进行比较,判断是否相同,如果有相同,则返回false,如果不同,则继续进行比较,这个算法的时间复杂度为o(N*N),容易想出来,但是浪费时间,往往面试题中第一个想法的解题思路基本上不是最优的解题思路。
思路二:(时间复杂度为O(logN))
另外一种想法就是把所有相同的字符串都放在一起,那么可以通过排序实现,把字符串从小到大排序起来,然后判断有没有相邻字符串是相同的,如果相同则返回false,如果不同则返回ture,因为排序算法的最小时间复杂度为O(logN),所以这个方法的时间复杂度可以减小到O(logN)。
思路三:(时间复杂度为O(N))
字符是所有内置基本类型中,除了bool类型意外最小的类型,它的范围只有0-255,所以对于这种小范围的数据类型,我们完全可以类似桶排序思路一样来统计每个字符出现的次数,建立一个大小为256的bool类型数组,刚开始初始化为false,然后遍历字符串,如果当前字符对应的bool数组为false,则将其置为ture,否则函数返回false。
因为字符总过也就256个,所以当字符串总长度大于256时,果断返回false。
(注意:对于大部分范围比较小的数据帅选或者排序问题,都可以考虑一下这个思路)
下面是这个思路的实现代码:
bool checkDifferent(string iniString) {
// write code here
int size=iniString.size();
if(size>256)
return false;
bool *isDifferent=new bool[256]();
for(unsigned char i=0;i<size;i++)
{
if(isDifferent[i])
return false;
isDifferent[i]=true;
}
return true;
}
<strong><span style="font-family:KaiTi_GB2312;font-size:24px;">思路四:(时间复杂度为O(N))</span></strong>
如果这道题目对应的数据范围只有0-32,那么我们可以想到int类型的二进制有32位,那么可以用其每一位的0,1表示对应字符有没有出现过,假如这道题目的字符串里只有a-z,那么就可以用这种方法实现,当字符串总长度大于32时候,肯定返回false。
下列是实现代码:
bool checkDifferent(string iniString) {
int size=iniString.size();
if(size>32)
return false;
int checker=0;
for(unsigned char i=0;i<size;i++)
{
int val=iniString[i];
if(checker&(1<<val))
return false;
checker|(1<<val);
}
return true;
}