位运算的最经典题目及解析C++

在C++编程和计算机科学中,位运算是一个常见且重要的概念。位运算是指直接对整数的二进制位进行操作,包括常见的与(AND)、或(OR)、取反(NOT)、异或(XOR)、左移(左位移)与右移(右位移)等。这些操作在算法优化、数据压缩、图像处理等领域都有广泛的应用。本文将通过一个经典的位运算题目来阐述其应用与解析。

题目:只出现一次的数字

题目描述:
给定一个整数数组,其中除了一个整数只出现一次外,其他每个整数都出现了两次。请编写一个函数,找到那个只出现一次的整数。

示例:

输入: [4, 1, 2, 1, 2]
输出: 4
输入: [2, 2, 1]
输出: 1

解题思路

我们可以利用位运算中的异或(XOR)操作来解决这个问题。异或操作有以下性质:

  1. 自反性:任何数与自己异或的结果是0。
  2. 交换律和结合律:A B C = A C B,顺序不影响结果。
  3. 与0异或:任何数与0异或的结果是它本身。

基于这些性质,我们可以得出一个有效的解决方案:

  • 对于数组中的所有元素进行异或操作,出现两次的数字由于自反性会互相抵消,最终得到的结果就是只出现一次的那个数字。

代码实现

下面是使用C++实现上述思路的代码:

#include <iostream>
#include <vector>

class Solution {
public:
    int singleNumber(std::vector<int>& nums) {
        int result = 0;
        for (int num : nums) {
            result ^= num;  // 对数组中的所有数字进行异或运算
        }
        return result;  // 返回只出现一次的数字
    }
};

int main() {
    Solution solution;
    std::vector<int> nums1 = {4, 1, 2, 1, 2};
    std::vector<int> nums2 = {2, 2, 1};

    std::cout << "Output for [4, 1, 2, 1, 2]: " << solution.singleNumber(nums1) << std::endl;
    std::cout << "Output for [2, 2, 1]: " << solution.singleNumber(nums2) << std::endl;

    return 0;
}

代码解析

  1. 类和方法定义:创建一个 Solution 类,其中包含 singleNumber 方法,该方法接受一个整数向量 nums 作为参数。
  2. 初始化结果:定义一个整数 result 初始化为0。
  3. 循环遍历:使用范围基于的 for 循环遍历数组中的每一个元素,执行 result ^= num 操作。
  4. 返回结果:最后返回 result,即只出现一次的整数。

复杂度分析

  • 时间复杂度:O(n),我们只遍历了一遍数组。
  • 空间复杂度:O(1),使用了一个额外的变量 result

扩展应用

除了这一问题,位运算还可以解决许多其他问题,例如:

  • 判断一个数是奇数还是偶数:可以通过与1进行与运算判断。
  • 交换两个数:通过异或可以在不使用额外变量的情况下交换两个数。
  • 计算汉明重量:计算一个整数的二进制表示中1的个数。

小结

位运算是计算机科学中一个高效且强大的工具,它能够让我们以极简的形式完成复杂的操作。通过对位运算的深入理解,程序员可以编写出更加高效的代码,解决一些看似复杂的问题。在本题中,我们通过使用异或操作成功找到了只出现一次的数字,充分展现了位运算的魅力。希望读者能够通过这个经典题目,进一步掌握位运算的使用,并在实际编程中灵活运用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值