136. Single Number-位运算,异或

Given an array of integers, every element appears twice except for one. Find that single one.

Note:
Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?

这题用到位运算异或

异或有下面的性质:

1、交换律:a ⊕ b = b ⊕ a

2、结合律:   a ⊕b ⊕ c = a ⊕ (b ⊕ c) = (a ⊕ b) ⊕ c;

3、对于任何数x,都有x^x=0,x^0=x

4、自反性: A XOR B XOR B = A xor  0 = A

假设nums = [2,1,3,1,2]

那么res = 0^2^1^3^1^2 = 0^(1^1)^(2^2)^3 = 3 

代码:
class Solution {
public:
    int singleNumber(vector<int>& nums) {
        int result = 0, n = nums.size();
        for (int i = 0; i<n; i++)
    		result ^= nums[i];     //利用异或的交换律:a^b = b^a 以及 结合律:a^b^c=(a^b)^c=a^(b^c)
    	return result;
    }
};

<think>我们正在讨论C#中的位异或运算(XOR),运算符为^。位异或运算在二进制位级别进行操作,其规则是:当两个对应位不同时结果为1,相同时结果为0。也就是说:$$位运算规则:0\oplus0=0,0\oplus1=1,1\oplus0=1,1\oplus1=0$$在C#中,位异或运算可以用于整数类型、枚举类型(实际上是整数类型的别名)以及布尔类型。此外,它还具有一些有趣的性质,如自反性(即一个异或自身为0)交换律等。下面我将详细介绍位异或运算的用法特性:###一、核心特性1.**运算规则**:```csharpinta=5;//二进制:0101intb=3;//二进制:0011intc=a^b;//二进制:0110→十进制6Console.WriteLine(c);//输出6```2.**数据类型支持**:-**整数类型**:包括`byte`,`sbyte`,`short`,`ushort`,`int`,`uint`,`long`,`ulong`。-**枚举类型**:因为枚举底层是整数,所以也可以使用异或运算。-**布尔类型**:布尔值的异或运算,即逻辑异或。注意,对于布尔类型,异或运算与逻辑异或相同。示例(布尔类型):```csharpboolx=true;booly=false;Console.WriteLine(x^y);//输出True(因为truefalse不同)```3.**重要性质**:-**自反性**:任何数异或自身结果为0,即`a^a=0`。-**与0异或**:任何数异或0结果为自身,即`a^0=a`。-**交换律结合律**:`a^b=b^a`,`(a^b)^c=a^(b^c)`。###二、应用场景1.**交换两个变量的值**(无需临时变量):```csharpintx=10;inty=20;//交换步骤:x=x^y;y=x^y;//此时y变成了原来的xx=x^y;//此时x变成了原来的y```解释:第一步后,`x`保存了`x^y`;第二步后,`y=(x^y)^y=x^(y^y)=x`;第三步后,`x=(x^y)^x=(x^x)^y=y`。2.**找出数组中唯一不重复的元素**:在一个数组中,所有元素都出现两次,只有一个元素出现一次,可以用异或找出这个元素。这是引用[2]中的示例。```csharppublicstaticintSingleNumber(int[]nums){intresult=0;for(inti=0;i< nums.Length;i++){result^=nums[i];}returnresult;}```原理:由于`a^a=0``0^a=a`,所以成对的数异或后会相互抵消,剩下只出现一次的数。3.**简单的数据加密/解密**:利用同一个密钥进行两次异或运算可以还原数据,如引用[3]所示。```csharpintplain=12345;//原始数据intkey=67890;//密钥intcipher=plain^key;//加密intdecrypted=cipher^key;//解密,得到原始数据```###三、复合赋值运算符`^=`类似于其他位运算符,异或也有复合赋值形式:```csharpintx=5;x^=3;//等同于x=x^3;结果x为6```###四、注意事项1.**与逻辑运算符的区别**:-`^`是位异或运算符,也可以用于布尔值(作为逻辑异或)。-逻辑与`&&`逻辑或`||`具有短路特性,而`^`不具备短路特性,因为它必须计算两个操作数。2.**类型转换**:当操作数类型不一致时,C#会自动进行隐式转换(例如将较小的整数类型转换为较大的整数类型),然后再进行异或运算。例如:```csharpbytea=1;intb=2;varc=a^b;//结果是int类型```3.**不能用于浮点数**:异或运算只能用于整数类型布尔类型,不能用于`float`或`double`,因为它们的内部表示不是纯二进制整数。###总结位异或运算(XOR)在C#中是一种强大的位操作工具,常用于:-交换变量值-查找数组中的唯一元素-简单加密解密-标志位切换(翻转特定位)其核心特性是自反性与0异或的特性,使得它在很多场景中非常高效。---§§相关问题§§1.如何使用位异或进行标志位的切换(翻转)?2.在数组中有两个只出现一次的元素(其余都出现两次),如何用异或找出它们?3.异或运算在图形处理中的应用例子有哪些?4.异或加密算法的安全性如何?为什么在实际中不常用?</think> ### C# 位异或运算(XOR)详解 位异或运算符 `^` 是 C# 中的二进制位运算符,用于对两个整数的二进制位进行逻辑异或操作。其核心规则为:**相同位为 0,不同位为 1**,即: $$ \text{结果位} = \begin{cases} 0 & \text{若 } \text{位}_A = \text{位}_B \\ 1 & \text{若 } \text{位}_A \neq \text{位}_B \end{cases} $$ --- #### 一、核心特性 1. **运算规则** 对两个整数的二进制位逐位比较: ```csharp int a = 5; // 二进制: 0101 int b = 3; // 二进制: 0011 int c = a ^ b; // 二进制: 0110 → 十进制 6 Console.WriteLine(c); // 输出 6 ``` 2. **关键性质** - **自反性**:$a \oplus a = 0$(任何数与自身异或结果为 0) - **归零性**:$a \oplus 0 = a$(任何数与 0 异或结果为其自身) - **可逆性**:$(a \oplus b) \oplus b = a$(两次相同异或还原原始值) 3. **数据类型支持** - **整数类型**:`int`, `long`, `byte` 等 - **布尔类型**:支持逻辑异或(非位运算- **枚举类型**:需显式转换为整数(如 `(int)MyEnum.Value`) --- #### 二、应用场景 1. **数据加密/解密**(基于可逆性) ```csharp int data = 12345; int key = 98765; int encrypted = data ^ key; // 加密 int decrypted = encrypted ^ key; // 解密还原原始数据 [^3] ``` 2. **查找唯一不重复元素** 在成对出现的数组中找出唯一未重复的元素: ```csharp // 引用[2]示例优化版 public static int SingleNumber(int[] nums) { int result = 0; foreach (var num in nums) result ^= num; // 成对元素相互抵消 return result; // 剩余元素即为唯一值 } ``` 3. **切换位状态(Toggle Bit)** 翻转特定二进制位: ```csharp int flags = 0b1100; int mask = 0b0100; // 目标切换位 int result = flags ^ mask; // 结果: 0b1000(第 3 位切换) ``` 4. **快速变量交换(无临时变量)** ```csharp int x = 10, y = 20; x ^= y; // x = 10 ^ 20 y ^= x; // y = 20 ^ (10 ^ 20) = 10 x ^= y; // x = (10 ^ 20) ^ 10 = 20 ``` --- #### 三、复合赋值运算符 `^=` ```csharp int state = 0b1010; state ^= 0b0101; // 等价 state = state ^ 0b0101 Console.WriteLine(Convert.ToString(state, 2)); // 输出 "1111" ``` --- #### 四、注意事项 1. **与逻辑运算符 `^` 的区别** - 对于整数:执行位级异或 - 对于布尔值:执行逻辑异或(非位运算) ```csharp bool b1 = true, b2 = true; Console.WriteLine(b1 ^ b2); // 输出 False(同真同假为假) ``` 2. **类型不匹配处理** 操作数类型不一致时,C# 自动进行类型提升(如 `byte` 转为 `int`)[^1]。 3. **禁用场景** - 浮点数(`float`/`double`)不支持位运算 - 结果溢出时需显式类型转换(如 `long result = (long)a ^ b`) --- ### 总结 位异或(XOR)的核心价值: 1. **高效数据加密**:利用可逆性实现轻量级加密 2. **唯一值定位**:基于自反性过滤重复项 [^2] 3. **位操作优化**:快速切换位状态,无临时变量交换值 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值