该题原址:​​https://leetcode-cn.com/problems/hamming-distance/​


问题描述

LeetCode 461.汉明距离 - Java_461


问题分析

找出两个数二进制相同位置的不同的个数之和.
考察位运算.
可以想到异或,两个数异或后不同为1,相同为0,因此就转换为求1的问题.
对于求1的问题可以看此文:​​计算二进制中1的个数-Java____[位运算思维]​​


代码演示

1. 使用java自带方法求解

/**
* 执行用时 : 1 ms, 在Hamming Distance的Java提交中击败了99.49% 的用户
* 内存消耗 : 32.2 MB, 在Hamming Distance的Java提交中击败了92.20% 的用户
*
*/
public static int hammingDistance(int x, int y) {
if(x == y) { return 0; } // 这条判断很关键,可以节省大部分内存,提高效率
return Integer.bitCount(x^y);
}
}



2. 异或后,利用求二进制中1的个数

public static int hammingDistance(int x, int y) {
int num = 0;
int temp = x^y;
while (temp != 0) {
temp = (temp - 1) & temp;
num++;
}
return num;
}



3.首先想出的笨方法(忘了异或那回事)

class Solution {
/**
* 执行用时 : 2 ms, 在Hamming Distance的Java提交中击败了68.93% 的用户
* 内存消耗 : 33.4 MB, 在Hamming Distance的Java提交中击败了77.38% 的用户
*/
public int hammingDistance(int x, int y) {
int num = 0;
int bigLen = 0;
if (x > y) {
bigLen = x;
} else {
bigLen = y;
}
int len = Integer.toBinaryString(bigLen).length();
for (int i = 0; i < len; i++) {
if ((x & 1) != (y & 1)) {
num++;
}
x = x >> 1;
y = y >> 1;
}
return num;
}
}



4. 上一种方法的优化(实际上性能一点没有提高)

public static int hammingDistance(int x, int y) {
int num = 0;
int temp;
if(x == y) { return 0; }
if(x>y) { // 保证y>x
temp = x;
x = y;
y = temp;
}

int len = Integer.toBinaryString(x).length(); // 先将小数的二进制位的不同的位数列出
for (int i = 0; i < len; i++) {
if ((x & 1) != (y & 1)) {
num++;
}
x = x >> 1;
y = y >> 1; // 比较之后两个数同时向右移一位
}

while(y!=0) { // 求出大数剩余位数的1的个数
y = (y-1)&y;
num++;
}
return num;
}

总结

要想有一个好的解决办法,看你能否想出他要考察的是什么知识.

该题两个数求相同位置的不同的值的个数.应该首先想到异或.

之后就是求1的方法,当然java基础牢固的话,就可以直接想到bitCount()方法.