2220-转换数字的最少位翻转次数
一次 位翻转 定义为将数字 x
二进制中的一个位进行 翻转 操作,即将 0
变成 1
,或者将 1
变成 0
。
- 比方说,
x = 7
,二进制表示为111
,我们可以选择任意一个位(包含没有显示的前导 0 )并进行翻转。比方说我们可以翻转最右边一位得到110
,或者翻转右边起第二位得到101
,或者翻转右边起第五位(这一位是前导 0 )得到10111
等等。
给你两个整数 start
和 goal
,请你返回将 start
转变成 goal
的 最少位翻转 次数。
示例 1:
**输入:** start = 10, goal = 7
**输出:** 3
**解释:** 10 和 7 的二进制表示分别为 1010 和 0111 。我们可以通过 3 步将 10 转变成 7 :
- 翻转右边起第一位得到:101 ** _0_** -> 101 ** _1 。_**
- 翻转右边起第三位:1 ** _0_** 11 -> 1 ** _1_** 11 。
- 翻转右边起第四位: ** _1_** 111 -> **_0_** 111 。
我们无法在 3 步内将 10 转变成 7 。所以我们返回 3 。
示例 2:
**输入:** start = 3, goal = 4
**输出:** 3
**解释:** 3 和 4 的二进制表示分别为 011 和 100 。我们可以通过 3 步将 3 转变成 4 :
- 翻转右边起第一位:01 ** _1_** -> 01 _ **0**_ 。
- 翻转右边起第二位:0 ** _1_** 0 -> 0 ** _0_** 0 。
- 翻转右边起第三位: ** _0_** 00 -> **_1_** 00 。
我们无法在 3 步内将 3 变成 4 。所以我们返回 3 。
提示:
0 <= start, goal <= 109
方法一:位运算
思路与算法
为了使得位翻转操作的次数最少,我们应当只对 start 与 goal 数值不同的二进制位执行翻转操作,而对应的最少次数即为这两个数字不同的二进制位数量。
为了求出 start 与 goal 不同的二进制位数量,我们可以计算两个数按位异或后的数值 tmp} = \textit{start} \oplus \textit{goal。根据异或运算的定义,tmp 某一二进制位为 1 当且仅当 start 与 goal 在该位数值不同。因此,tmp 的二进制表示中 1 的数量即为 start 与 goal 不同的二进制位数量。我们计算并返回该值即可。
关于如何计算一个整数二进制表示中 1 的数量,读者可以参考「191. 位1的个数」的题解 ,本文中我们将使用循环检查二进制位的方法计算。
代码
1 | class Solution { |
1 | class Solution: |
复杂度分析
时间复杂度:O(\log M),其中 M = \max(\textit{start}, \textit{goal}) 为两数的较大值,即为计算异或数值中 1 的位数的时间复杂度。
空间复杂度:O(1)。
Comments