跳转至

3226. 使两个整数相等的位更改次数

题目描述

给你两个正整数 nk

你可以选择 n二进制表示 中任意一个值为 1 的位,并将其改为 0。

返回使得 n 等于 k 所需要的更改次数。如果无法实现,返回 -1。

 

示例 1:

输入: n = 13, k = 4

输出: 2

解释:
最初,nk 的二进制表示分别为 n = (1101)2k = (0100)2

我们可以改变 n 的第一位和第四位。结果整数为 n = (0100)2 = k

示例 2:

输入: n = 21, k = 21

输出: 0

解释:
nk 已经相等,因此不需要更改。

示例 3:

输入: n = 14, k = 13

输出: -1

解释:
无法使 n 等于 k

 

提示:

  • 1 <= n, k <= 106

解法

方法一:位运算

如果 $n$ 和 $k$ 的按位与结果不等于 $k$,说明 $k$ 存在某一位为 $1$,而 $n$ 对应的位为 $0$,此时无法通过改变 $n$ 的某一位使得 $n$ 等于 $k$,返回 $-1$;否则,我们统计 $n \oplus k$ 的二进制表示中 $1$ 的个数即可。

时间复杂度 $O(\log n)$,空间复杂度 $O(1)$。

1
2
3
class Solution:
    def minChanges(self, n: int, k: int) -> int:
        return -1 if n & k != k else (n ^ k).bit_count()
1
2
3
4
5
class Solution {
    public int minChanges(int n, int k) {
        return (n & k) != k ? -1 : Integer.bitCount(n ^ k);
    }
}
1
2
3
4
5
6
class Solution {
public:
    int minChanges(int n, int k) {
        return (n & k) != k ? -1 : __builtin_popcount(n ^ k);
    }
};
1
2
3
4
5
6
func minChanges(n int, k int) int {
    if n&k != k {
        return -1
    }
    return bits.OnesCount(uint(n ^ k))
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
function minChanges(n: number, k: number): number {
    return (n & k) !== k ? -1 : bitCount(n ^ k);
}

function bitCount(i: number): number {
    i = i - ((i >>> 1) & 0x55555555);
    i = (i & 0x33333333) + ((i >>> 2) & 0x33333333);
    i = (i + (i >>> 4)) & 0x0f0f0f0f;
    i = i + (i >>> 8);
    i = i + (i >>> 16);
    return i & 0x3f;
}

评论