题目描述
请实现一个算法,确定一个字符串的所有字符是否全都不同。这里我们要求不允许使用额外的存储结构。
给定一个string iniString,请返回一个bool值,True代表所有字符全都不同,False代表存在相同的字符。保证字符串中的字符为ASCII字符。字符串的长度小于等于3000。
测试样例:
"aeiou"
返回:True
"BarackObama"
返回:False
题目分析
1.这道题用java是比较方便的,因为它支持的正则表达式可以比较方便的解决这样的问题。
public boolean checkDifferent(String iniString) {
return !iniString.matches(".*(.)(.*\\1).*");
}
2.我想到的是利用ASCII码的字符数最多256个,所以可以利用hash表来统计字符出现的个数,当字符数大于256个时肯定有重复的,小于256个的时候就统计出现的个数,当个数大于1时,返回false; 由于题目说的是不能使用额外的存储结构,所以这个方法还可以改进。
bool checkDifferent(string iniString) {
int hash[256] = {0};//初始化hash表为0
int i;
//用hash表统计每个字符出现的次数
if (iniString.length() > 256) return false;
for (i=0; iniString[i]!='\0'; i++)
{
hash[iniString[i]] ++;
if (hash[iniString[i]] > 1){
return false;
}
}
return true;
}
3.利用原址排序,以时间换空间,对原字符数组进行排序,这里推荐快排的划分方法。
Parition基于快速排序的partition,可以边排序边找重复,也即是每次partition之后,判断中间key元素与两边元素是否相同,相同则返回false,不同再进行下一轮partition.时间复杂度也是O(nlongn),但要比排序速度快。
bool quick_check(string &str,int low,int high){
int first = low,last = high;
char key = str[first];
if (low>=high)
return true;
while(first<last){
while(first <last && str[last] >= key)
last--;
str[first] = str[last];
while(first<last && str[first] <= key)
first++;
str[last] = str[first];
}
str[first] = key;
if (first>low && str[first] == str[first-1])
return false;
if (first<high && str[first] == str[first+1])
return false;
return quick_check(str,low,first-1) && quick_check(str,first+1,high);
}