package codinginterview;
/**
*
* 实现一个算法来判断一个字符串中的字符是否唯一(即没有重复).
* 不能使用额外的数据结构。 (即只使用基本的数据结构)
* @author mingdong.cheng
*
*/
public class CheckUniqueChar {
/**
* 对于ASCII字符,我们需要256位
* 该算法的时间复杂度为O(n)
* @param s
* @return
*/
public static boolean isUnique(String s) {
final boolean[] a = new boolean[256];
int len = s.length();
for (int i = 0; i < len; i++) {
int v = (int) s.charAt(i);
if (a[v])return false;
a[v] = true;
}
return true;
}
/**
* 通过位运算来减少空间的使用量。
* 用每一位表征相应位置字符的出现。
* 对于ASCII字符,我们需要256位,即一个大小为8的int 数组a即可。
* 这里的关键是要把字符对应的数字,映射到正确的位上去。
* 比如字符'b'对应的 代码是98,那么我们应该将数组中的哪一位置为1呢?
* 用98除以32,得到对应数组a的下标:3。
* 98对32取模得到相应的位:2。
* 该算法的时间复杂度为O(n),需要的内存空间更小
* @param s
* @return
*/
public static boolean isUnique2(String s) {
final int[] a = new int[8];//位运算时,256个字符需要8个整型数来表征存储位:256/32=8
int len = s.length();
for (int i = 0; i < len; i++) {
int v = (int) s.charAt(i);
int idx=v/32,shift=v%32;
int b=a[idx]&(1 << shift);
if (b!=0)return false;
a[idx]|=(1 << shift);
}
return true;
}
/**
* 如果字符集只是a-z(或是A-Z)仅26个字符,那就更好办了,用位运算只需要一个整型数即可。
* @param s
* @return
*/
public static boolean isUnique3(String s) {
int check=0;//位运算可映射表征32位
int len = s.length();
for (int i = 0; i < len; i++) {
int v = (int) s.charAt(i);
int b=check&(1 << v);
if (b!=0)return false;
check|=(1 << v);
}
return true;
}
public static void main(String[] args) {
String s1 = "i am daniel cheng.";
String s2 = "abcdefghijklmnopqrstuvwxyzABCD1234567890";
String s3 = "abcdefghijklmnopqrstuvwxyz";
String s4 = "01234567892";
System.out.println(isUnique(s1));
System.out.println(isUnique2(s2));
System.out.println(isUnique3(s3));
System.out.println(isUnique3(s4));
}
}
转载于:https://my.oschina.net/mingdongcheng/blog/143857