数据结构之位运算

本文介绍了位运算的基本操作,如或、与、异或,并通过实例讲解了如何利用位运算原地交换两个int变量、计算整数二进制中1的个数,以及在特定数组中找出出现次数为奇数的元素。同时,还讨论了相关面试题的解题思路。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.基本位运算符

  • :如果两个值有一个为1,或结果为1,否则为0;
  • :如果两个值都为1,与结果为1,否则为0;
  • 异或:如果两个值不同,异或结果为1,否则为0;

2.经典应用

2.1 原地交换两个int变量

  • 可以通过相加来实现
int a = 3, b = 4;
a = a + b;
b = a - b;
a = a - b;
  • 用异或来实现
int x = 3, y = 4;
x = x ^ y;
y = x ^ y;
x = x ^ y;

异或运算支持运算的交换律结合律
y = x ^ y = (x ^ y) ^ y = x ^ (y ^ y) = x ^ 0 = x:x 的值成功赋给y。
x = x ^ y = (x ^ y) ^x = ( x ^ x) ^ y = 0 ^ y = y,同理y的值成功赋给x。

2.2 整数的二进制表达式中有多少个1

  • x & (x - 1)代表将x的二进制表达中最右边的1变为0。
  • 求二进制1的个数模板:
while(x) {
	x = x & (x - 1);
	ans++;
}
  • 原理:把一个整数减去一,再和原来的整数做相与运算,会把最右边的1变为0,根据上述思想,二进制x中有多少个1,就要进行多少次相与的运算,例如 x=9;
第一步:             第二步:
    1 0 0 1             1 0 0 0
 &  1 0 0 0           & 0 1 1 1
 ————————————        ————————————
    1 0 0 0             0 0 0 0

2.3 在其它数都出现偶数次的数组中找出两个出现一次的数

  • 解析:如果把数组所有的数字都依次异或之后,则可以消掉成对出现的次数,还有2个是单一的,异或值不为0,表现在二进制中肯定有一位是1,那么这两个数字在该位肯定有一个为1,一个为0。
  • 核心代码
vector<int> FindNumsAppearOnce(vector<int>& array) {
    int sum = 0;
    for (auto arr : array) {
	    sum = sum ^ arr;
	 }
	int x = 0, y = 0, count = 0;
    while ((sum & 1) == 0) {
        count++;
        sum = sum >> 1;
    }
    for (auto arr : array) {
         if ((arr >> count) & 1) {
             x = x ^ arr;
         } else {
             y = y ^ arr;
         }
    }
    return {min(x, y), max(x, y)};
}

2.4 在其它数都出现K次的数组中找出出现一次的数

  • 核心代码
int foundOnceNumber(vector<int>& arr, int k) {
    int res = 0;
    for (int i = 0; i < 32; i++) {
        int sum = 0;
        for (int j = 0; j < arr.size(); j++) {
            sum += (arr[j] >> i) & 1;
        }
        if (sum % k > 0) {
           res = res | (1 << i);
        }
    }
    return res;
}

3.位运算符的相关面试题

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值