返回

每日好题 3.2.1:解锁位运算的奥秘

见解分享

响应掘金的每日好题 3.2.1,我们开启一次位运算的探索之旅!位运算是一种强大的工具,尤其是在解决编程问题时。在今天的题目中,我们将解锁位运算的奥秘,使用异或运算符 (^) 来解决一个有趣的挑战。

异或运算符的魔力

异或运算符 (^) 是位运算的一个基本运算符。它的工作原理很简单:对于给定的两个二进制数,它对每一对相应的位执行异或运算。异或运算的规则如下:

  • 如果两个位都为 0,则结果为 0。
  • 如果两个位都为 1,则结果为 0。
  • 如果两个位不同(一个为 0,另一个为 1),则结果为 1。

题目详解

今天的题目要求我们找到一个数组中唯一一个出现奇数次的数字,而其他所有数字都出现偶数次。为了解决这个问题,我们可以利用异或运算符的特殊性质。

异或运算符的性质

异或运算符具有几个有用的性质,包括:

  • 交换律: a ^ b = b ^ a
  • 结合律: (a ^ b) ^ c = a ^ (b ^ c)
  • 零元素: 任何数与 0 异或的结果都为该数本身。
  • 自反性: 任何数与自身异或的结果都为 0。

解题步骤

基于这些性质,我们可以使用异或运算符来解决这个问题:

  1. 初始化一个变量 result 为 0。
  2. 遍历数组中的每个元素 nums[i]。
  3. 将 result 与 nums[i] 进行异或运算:result ^= nums[i]。
  4. 继续遍历数组,直到遍历完成。
  5. 返回 result,它就是出现奇数次的唯一数字。

证明

对于数组中的任何数字 nums[i],如果它出现偶数次,那么与它进行异或运算两次,即 result ^= nums[i] ^= nums[i],结果将为 0,因为异或自反。

对于出现奇数次的数字 nums[j],它只与 result 异或一次,根据异或的交换性和结合性,result 将变为 result ^ nums[j]。由于 0 是异或的零元素,因此最终 result 的值为 nums[j]。

示例代码

int singleNumber(int[] nums) {
    int result = 0;
    for (int num : nums) {
        result ^= num;
    }
    return result;
}

其他应用

位运算在计算机科学中还有许多其他应用,包括:

  • 掩码: 使用位掩码可以隔离或设置二进制数的特定位。
  • 位移: 位移运算可以将二进制数向左或向右移动一定位数。
  • 计数置位: 位运算可以快速计算二进制数中置位的数量。

通过掌握位运算,我们可以编写更高效、更简洁的代码。因此,深入理解位运算及其应用对于成为一名熟练的程序员至关重要。