提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
问题描述
给定一个字符串数组 words,请计算当两个字符串 words[i] 和 words[j] 不包含相同字符时,它们长度的乘积的最大值。假设字符串中只包含英语的小写字母。如果没有不包含相同字符的一对字符串,返回 0。
重点剖析
该题若要暴力求解,其实思路很简单,采用循环遍历即可,但是这样时间复杂度太高,我们还是需要采用更高效的方法。本题的重点是判断两个字符串是否存在重复的字符,这是本题的重点所在。
思路分析
- 我们需要找到判断两个字符串是否存在相同字符的方法,我们可以试图用整数的二进制形式来表示,例如,若‘a’存在于字符串中,则表示该字符串的整数二进制形式在右边第一个位置的数字为1,其他以此类推;
- 基于第一步,我们很容易看出判断两个字符串是否有相同字符的方式是对两个二进制数进行与的操作,若有相同的,则结果一定不为0,反之没有相同的话结果为0,这就是我们判断的依据;
代码
//创建存放每个字符串对应的整数的数组
int[] flags = new int[words.length];
//根据字符串中包含的字符,求出对应的二进制数
for (int i =0;i< words.length;i++) {
for (char ch : words[i].toCharArray()) {//记住这种形式,掌握不牢,将字符串转为字符数字后取每个字符
flags[i] |= 1 << (ch - 'a'); //注意是将1向左移动
}
}//到这里每个字符串对应的整数就计算完毕
//开始判断是否存在相同字符,并且计算乘积
int result = 0;
for (int i = 0; i < words.length; i++) {
for (int j = i + 1; j < words.length; j++) {
if ((flags[i] & flags[j]) == 0) {//如果两个整数与操作为0,说明没有相同的字符
//计算乘积,并且取最大值
result = Math.max(result, words[i].length() * words[j].length());
}
}
}
return result;
总结
提示:重点记住这种方法:即使用二进制数的形式保存字符串中出现的字符,通过这种方式我们能使程序在时间和空间上有很大的提升。