题目1318:或运算的最小翻转次数

题目描述

给你三个正整数a、bc

你可以对ab的二进制表示进行位翻转操作,返回能够使按位或运算a OR b == c成立的最小翻转次数。

「位翻转操作」是指将一个数的二进制表示任何单个位上的1变成0或者0变成1

示例1:

输入:a = 2, b = 6, c = 5
输出:3
解释:翻转后 a = 1 , b = 4 , c = 5 使得 a OR b == c

示例2:

输入:a = 4, b = 2, c = 7
输出:1

示例3:

输入:a = 1, b = 2, c = 3
输出:0

提示:

1 <= a <= 10^9

1 <= b <= 10^9

1 <= c <= 10^9

解答技巧

本题需要用到一些位运算的知识:

由于在或(OR)运算中,二进制表示的每一位都是独立的,即修改ab二进制表示中的第i位,只会影响a OR b中第i位的值,因此我们可以依次枚举并考虑每一位。注意到a、bc均小于10^9,它们的二进制表示最多有30位(包含31个二进制位的数最小为2^30 = 1073741824,已经大于10^9),因此我们只需要从低位到高位枚举这30位即可。

a、bc二进制表示的第i位分别为bit_a、bit_bbit_c,根据bit_c的值,会有以下两种情况:

我们将每一位的翻转次数进行累加,在枚举完所有位之后,就得到了最小翻转次数。

class Solution:
    def minFlips(self, a: int, b: int, c: int) -> int:
        ans = 0
        for i in range(32):
            bit_a, bit_b, bit_c = (a >> i) & 1, (b >> i) & 1, (c >> i) & 1
            if bit_c == 0:
                ans += bit_a + bit_b
            else:
                ans += int(bit_a + bit_b) == 0
        return ans

复杂度分析:

时间复杂度:O(\log C),其中C为常数,在本题中,C的值为10^9O(\log C)等价于C的位数,也就是我们需要枚举的位数。

空间复杂度:O(1)。