leetcode汉明距离总和
这道题,关键在于时间的控制,想一下之前学的ElasticSearch的查找,用的是倒排索引,就是为了在海量数据中能快速定位到需要的文档:
文章链接:https://blog.csdn.net/weixin_43624549/article/details/117125397?spm=1001.2014.3001.5501
那么,这道题要是一般的查找的思路:
1:先把每一个num[i]转换成二进制,保存到一个String数组中;
2:通过i=0;i<num.length();i++;和j=i+1;i<num.length();j++;
两层循环来判断所有的两两对比的结果,循环的时候直接加起来
3:即可得到想要的结果。
这种解法是典型的BF解法,暴力简单,且时间超时不通过。
代码如下:
class Solution {
public int totalHammingDistance(int[] nums){
String[] tem = new String[nums.length];
for (int i=0;i<nums.length;i++) {
tem[i] = Integer.toBinaryString(nums[i]);
}
int sum=0;
for (int i=0;i<nums.length;i++){
for (int j=i+1;j<nums.length;j++){
sum += comp(tem[i],tem[j]);
}
}
return sum;
}
public int comp(String s1,String s2){
int result=0;
int i1=s1.length()-1;
int i2=s2.length()-1;
while(i1>=0 && i2>=0){
if (s1.charAt(i1) != s2.charAt(i2)){
result++;
}
i1--;
i2--;
}
if (i1<0){
for (int i=i2;i>=0;i--){
if (s2.charAt(i)!='0'){
result++;
}
}
}
if (i2<0){
for (int i=i1;i>=0;i--){
if (s1.charAt(i)!='0'){
result++;
}
}
}
return result;
}
}
然后,类比ElasticSearch
的倒排索引,此问题也可以看每个num[i]
上的第j位上的1和0的个数,记录这一位上的1和0分别出现在哪些num[i]
。
这里的num[i]
就可以类比成ElasticSearch中的doc文档,然后1和0就是关键字。
求出分别每一位上1
和0
的个数之积
,再把每一位上的01个数积
求和,就为待求结果。
AC代码如下:
class Solution {
static int maxL=0;
public int totalHammingDistance(int[] nums){
//找出最多得比多少位:
for(int i=0;i<nums.length;i++){
if (nums[i]>maxL){
maxL=nums[i];
}
}
int numBit=Integer.toBinaryString(maxL).length();
int result=0;
//计算每一位上的1的个数,再计算每位上的0的个数,二者相乘,即为这一位上的距离值
int in=0;
while (in<numBit) {
//记录第in位上的所有1和0
int i1 = 0, i0 = 0;
for (int i = 0; i < nums.length; i++) {
if (((nums[i] >> in) & 1) == 1) {
i1++;
}
if (((nums[i] >> in) & 1) == 0) {
i0++;
}
}
result += i1 * i0;
i1=0;
i0=0;
in++;
}
return result;
}
}
LeetCode每日一题记录。