例如当前有两个字符串String s 和String t,找出这两个字符串中含有相同的字符并返回,
算法一(效率最差的):
/**
*
* @param s
* @param t
* @return 返回值未去重
*/
static char []solution(char[] s,char[] t) {
char[] chars = new char[Math.max(s.length,t.length)];
int index = 0;
for (int i = 0;i < s.length;i ++) {
for (int j = 0;j < t.length;j ++) {
if (s[i] == t[j]) {
chars[index ++] = s[i];
}
}
}
char[] result= new char[index];
System.arraycopy(chars,0,result,0,index);
return result;
}
这种算法效率不高,复杂度为O(n2);
接下来看效率更高的算法二:
/**
*
* @param s
* @param t
* @return 返回值未去重
*/
static char[]solution2(char[] s,char[] t) {
HashSet<Character> set = new HashSet<>();
char[] chars = new char[Math.max(s.length,t.length)];
int index = 0;
for (char c : s)
set.add(c);
int res = 0;
for (char c : t) {
if (!set.add(c)) {
chars[index ++] = c;
}
}
char[] result= new char[index];
System.arraycopy(chars,0,result,0,index);
return result;
}
算法二巧用了HashSet数据结构,HashSet里使用HashMap实现的,add方法的返回值代表HashSet里是否有这个char值,如果有则是重复的,及找到了相同的字符,但是这还不是效率最高的,接下来看最优的算法三:
/**
*
* @param s
* @param t
* @return 返回值未去重
*/
static char [] findRepeatCharZ(char[] s,char[] t) {
char [] a = new char['z' - 'A' + 1];
char[] tmp = new char['z' - 'A' + 1];
for (char c : s) {
a[c - 'A'] = 1;
}
int i = 0;
for (char c : t) {
if (a[c - 'A'] == 1) {
tmp[i ++] = (c);
}
}
char[] result= new char[i];
System.arraycopy(tmp,0,result,0,i);
return result;
}
这个算法活用了ascii值之间的差值,在字符集s中通过计算字符在数组a中的index并将index的值设置为1,再在字符集t中计算每一个字符index查找这个index在a中对应的值是否为1,如果是1,那t中当前计算的这个字符就是两个字符集都有的相同字符;这个算法可以推倒到n个字符串中有哪些相同的字符:
/**
*
* @param s
* @param t
* @return 返回值未去重
*/
static char [] findRepeatCharZ(char[] ...strings) {
if (strings == null || strings.length == 0) {
return null ;
}
if (strings.length == 1) {
return strings[0];
}
char[] reslut = findRepeatCharZ(strings[0],strings[1]);
for (int i = 2;i < strings.length;i ++) {
reslut = findRepeatCharZ(reslut,strings[i]);
}
return reslut;
}
这个算法也可以推倒查找重复中文汉字的算法,由于中文的范围比较广,所以占用的内存空间可能会比较大,但所有的中文个数也才数万个,也只需要几十k字节就可以了,但是可能char类型装不下所有的中文,可能需要使用int类型来作为index数组类型,算法这里就不给出了