leetcode
leetcode 2101 ~ 2150
最小异或

最小异或

难度:

标签:

题目描述

代码结果

运行时间: 23 ms, 内存: 16.0 MB


/*
 * 题目思路:
 * 1. 找出num2中二进制表示中1的个数(即置位数)。
 * 2. 创建一个新的数x,使其二进制表示中1的个数与num2相同。
 * 3. 使得x XOR num1的结果最小。为了达到这个目的,我们需要尽可能让x与num1相同。
 */
import java.util.stream.IntStream;

public class Solution {
    public int minimizeXor(int num1, int num2) {
        int countOnes = Integer.bitCount(num2); // 获取num2中1的个数
        int[] result = {0};
        int[] count = {countOnes};

        // 将num1的位从高到低遍历,尽可能将num1的1位保留
        IntStream.range(0, 32).map(i -> 31 - i).filter(i -> (num1 & (1 << i)) != 0).forEach(i -> {
            if (count[0] > 0) {
                result[0] |= (1 << i);
                count[0]--;
            }
        });

        // 如果还没有达到需要的1的个数,则从低位开始补1
        IntStream.range(0, 32).filter(i -> (result[0] & (1 << i)) == 0).forEach(i -> {
            if (count[0] > 0) {
                result[0] |= (1 << i);
                count[0]--;
            }
        });

        return result[0];
    }
}

解释

方法:

该题解的核心思路是调整 num1 的二进制表示,使其包含的 1 的个数与 num2 相同,同时保持其值尽可能小。首先,计算 num1 和 num2 的二进制表示中 1 的个数(置位数),分别为 c1 和 c2。如果 num1 的置位数多于 num2(c1 > c2),则通过将 num1 与 (num1 - 1) 进行按位与操作去除最低位的 1 直到两者的置位数一致。如果 num1 的置位数少于 num2(c1 < c2),则通过将 num1 与 (num1 + 1) 进行按位或操作添加最低位的 0 直到置位数一致。这种方法保证了 num1 调整后的值是最小的符合条件的值。

时间复杂度:

O(b)

空间复杂度:

O(1)

代码细节讲解

🦆
题解中提到,通过将num1与(num1 - 1)进行按位与操作去除最低位的1,为什么这样的操作可以保证去掉的是最低位的1?
在二进制表示中,num1与(num1 - 1)进行按位与操作的效果是将num1的最低位的1变为0,并且保持该位之后的所有位不变。这是因为从二进制的角度看,如果num1的某位是1,那么从这一位到最右端的所有位在num1-1中都会变成0,并且这一位会变成0。因此,num1与(num1 - 1)的按位与操作,实际上是把num1的最低位的1和之后的所有0变成了0,达到了去除最低位1的目的。
🦆
在增加置位数的过程中,为什么选择将num1与(num1 + 1)进行按位或操作,这样的操作是否总是能正确地只添加一个1位?
当我们将num1与(num1 + 1)进行按位或操作时,操作的效果是在num1的最低位的0之前添加一个1。这是因为num1的二进制表示中最低位的0,在num1+1中会变成1,而num1中所有低于这个位的1会在num1+1中变成0然后再变回1(由于进位)。因此,num1与(num1 + 1)的按位或结果是在原来的num1基础上在最低的0位转变为1,这确保了只增加一个1位。
🦆
题解中提到,这种方法可以保证调整后的num1是最小的符合条件的值。如何理解这个“最小”是如何被保证的?
在调整置位数的操作中,通过选择性地去除最低位的1或添加到最低位的0,我们优先保留了较高位的1,这样可以保证数值尽可能小。例如,去除较高位的1会导致数值减小更多,而我们的操作避免了这一点,只去除或添加最低位的。因此,通过这种方式调整num1,可以确保在满足置位数与num2相同的前提下,num1的数值是最小可能的,这就保证了num1是最小的符合条件的值。

相关问题