位运算
题目
想法
- n == k 直接返回 0
- n & k != k, 直接返回 -1 (从题目来说,只能将位的值 从1改为0,&:只有两个数中位的数都是1,才为1,所以符合答案的一定能等于 k)
- 逐位对比,只要不相等就累加 1,直到等于 0,最后返回累加值
解答
/**
* 执行用时分布 0 ms 击败 100.00% 复杂度分析 消耗内存分布 39.83 MB 击败 50.85%
*/
public int minChanges(int n, int k) {
// 相等的不需要更改
if (n == k){
return 0;
}
int temp = n & k;
// 从题目来说,只能将位的值 从1改为0,&:只有两个数中位的数都是1,才为1,所以符合答案的一定能等于 k
if (temp != k){
return -1;
}
int change = 0;
// int 4 字节,32 位
for (int i = 0; i < 32; i++) {
// n & 1 以及 k & 1 都是用于判断当前第一位(二进制位最右边)是否是 1,进而用于判断这两个数中这两位是否是一样的
if ((n & 1) != (k & 1)){
change++;
}
n >>= 1;
k >>= 1;
}
return change;
}
优化
看了官解的位运算,我发觉我的解法也可以在简便一点点
/**
* 执行用时分布 0 ms 击败 100.00% 复杂度分析 消耗内存分布 39.65 MB 击败 92.56%
*/
public int minChanges(int n, int k) {
if (n == k){
return 0;
}
// 从题目来说,只能将位的值 从1改为0,&:只有两个数中位的数都是1,才为1,所以符合答案的一定能等于 k
if ((n & k) != k){
return -1;
}
// n ^ k: 异或运算,两个数位中,相同为0,不同为1
// 那么也就是意味着,相同的位数归于 0 了,剩下的就是需要修改的,那么剩下就只需要计算位中 1的 个数即可
return Integer.bitCount(n ^ k);
}