原文:Implement an algorithm to determine if a string has all unique characters. What if you can not use additional data structures?
译文:实现一个算法来判断一个字符串中的字符是否唯一(即没有重复).不能使用额外的数据结构。 (即只使用基本的数据结构)
解答:首先需要确定构成字符串的字符集有多大,是ASCII还是26个英文字母,对于不同的字符集有不同的解法。
以字符集是ASCII为例,我们可以使用一个256大小的boolean数组,数组初始化为false,遍历一遍字符串中的字符,当bool数组对应位置的值为真, 表明该字符在之前已经出现过,即可得出该字符串中有重复字符。否则将该位置的bool数组 值置为true。
package test;public class Test {
public static void main(String args[]){
System.out.println(isRepeat("abcd"));
}
public static boolean isRepeat(String s){
/**
* 该数组默认是false
*/
boolean[] bool = new boolean[256];
/**
* 遍历一遍字符串字节
* 当bool数组对应位置的值为真, 表明该字符在之前已经出现过,
* 即可得出该字符串中有重复字符,
* 否则将该位置的bool数组值置为true。
*/
for(byte a:s.getBytes()){
if(bool[a])
return true;
else
bool[a] = true;
}
return false;
}
}
这是一种解题思路,还可以通过位向量来减少空间的使用量。对于ASCII字符,我们需要256位,一个int型的数有4个字节,也就是32位,即一个长度为8的int 数组a即可。这里的关键是要把字符对应的数字,映射到正确的位上去。a[0]表示第1~32个数(0~31),a[1]表示第33~64个数(32~63)······
package test;
public class Test {
public static void main(String args[]){
System.out.println(isRepeat("abcdsa"));
}
public static boolean isRepeat(String s){
/**
* 该数组默认是false
*/
int[] ints = new int[8];
final int CONSTANT = 32;
for(byte a:s.getBytes()){
//商,判断在哪个数组
int ids = a / CONSTANT;
//余数,判断在数组的第几位
int shift = a % CONSTANT;
/**
* 当前位是1,则返回true,说明重复
* 当前位是0,则置为1。
*/
if((ints[ids] & 1<< shift) > 0)
return true;
else
ints[ids] = ints[ids] | 1<< shift;
}
return false;
}
}
关于位向量的几篇文章: