【题目描述】
请实现一个算法,确定一个字符串的所有字符是否全都不同。这里我们要求不允许使用额外的存储结构。
给定一个string iniString,请返回一个bool值,True代表所有字符全都不同,False代表存在相同的字符。保证字符串中的字符为ASCII字符。字符串的长度小于等于3000。
测试样例:
1."aeiou" 返回:True
2."BarackObama" 返回:False
【思路1】暴力法,时间复杂度为。
两层for循环,依次比较,发现相同字符就返回false。
public boolean checkDifferent1(String iniString) {
for (int i = 0; i < iniString.length(); i++)
for (int j = i + 1; j < iniString.length(); j++) {
if (iniString.charAt(i) == iniString.charAt(j))
// if ((str.charAt(i)^str.charAt(j))==0) //异或
return false;
}
return true;
}
【思路2】哈希法,时间复杂度为。
字符编码是ASCII字符集,则总共只有256个字符;若为Unicode编码,则总共有65536。
对字符串的处理如下:
1) 如果字符串长度大于256,则必然有重复的字符出现,返回false;
2)如果字符串长度小于256,构建一个长度为256的boolean数组,索引值即为字符编码,则对每个元素从i = 0 ~ iniString.length() - 1进行遍历。若字符重复出现,返回false。
根据抽屉原理,判断前257个字符即可,时间复杂度为O(1),空间复杂度为O(1)。
public boolean checkDifferent2(String iniString) {
if (iniString.length() > 256) {
return false;
}
boolean[] char_set = new boolean[256];//不用额外空间就是空间复杂度O(1)
for (int i = 0; i < iniString.length(); i++) {
char val = iniString.charAt(i);
if (char_set[val])
return false;
char_set[val] = true;
}
return true;
}
【思路3】排序 时间复杂度
对字符进行排序,然后线性检查相邻元素是否有重复。Arrays类中的sort()使用的是“经过调优的快速排序法”,时间复杂度为O(nlogn)。
public boolean checkDifferent3(String iniString) {
if (iniString.length() > 256) {
return false;
}
char[] char_set= iniString.toCharArray();
Arrays.sort(char_set);
for(int i=1;i<char_set.length;i++) {
if(char_set[i]==char_set[i-1])
return false;
}
return true;
}
【思路4】正则表达式
大神写的,再次感慨正则的强大!!!!!!!!
public boolean checkDifferent(String iniString) {
return !iniString.matches(".*(.)(.*\\1).*");
}
.:代表任意一个字符
.*:代表任意一个字符后面有0个或多个字符
(.):选择字符中任意一个字符进行复制 和后面的(.*\\1)结合进行判断是否后面存在一个字符与它相同
(.)(.*\\1):匹配案例 a*a(即首尾相同的abcsa)
(.)(.*\\1).*:匹配案例 a*a*
.*(.)(.*\\1):匹配案例 *a*a
.*(.)(.*\\1).*:匹配案例 *a*a*