题目描述
问题分析
前置知识
其一,在计算机刚入门时,我们都学过与、或、非、异或运算,这道题用到的就是异或运算。它用符号 ^
表示。它的基本特性可以用真值表来理解:
A | B | A ^ B |
---|---|---|
0 | 0 | 0 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 0 |
也就是说,当A和B其中只有一个为真时,结果才为真。
并且最重要的是,这种计算可以推广到多位数的二进制数,用于求两个数之间的差异性。
举例:
假定有两个八位的二进制数:
-
a=10110110
-
b=11001010
计算a⊕b:
位索引 | a | b | a ⊕ b |
---|---|---|---|
7 | 1 | 1 | 0 |
6 | 0 | 1 | 1 |
5 | 1 | 0 | 1 |
4 | 1 | 0 | 1 |
3 | 0 | 1 | 1 |
2 | 1 | 0 | 1 |
1 | 1 | 1 | 0 |
0 | 0 | 0 | 0 |
逐位异或的结果,对于每一位,表示的是两个数字在该位上的差异情况。因此,异或运算的结果可以视为 "相异性检测" ,即结果的每一位为1表示两个数在该位不同,为0表示相同。
那么我们现在明白了,异或运算可以用来检测数字是否相同、有多么相同。
那这又如何能用来做这道题呢?这里可以介绍异或运算的两个性质了:
性质1:任意数与0异或等于它本身
设 a 是一个二进制数,假设它的第 i 位为 ai(可以是0或1)。0的第 i 位为0。
根据异或运算的规则:
因此,对于每一位 i,有 ai⊕0=ai。也就是说,异或运算后每一位都保持原值不变。
因此:a⊕0=a
性质2:任意数与自己异或等于0
设 a 是一个二进制数,假设它的第 i位为 ai(可以是0或1)。
根据异或运算的定义,两个相同的位异或结果为0:
因此,对于每一位 i,有 ai⊕ai=0。所有的位异或后,结果仍然是0。
因此:a⊕a=0
了解上述知识后,这道题便十分简单了。
解题思路
其他所有数字都是成对的,只有一个数字是单独的。这让我们想到“任意数与自己异或等于0”,也就是说,成对的数字可以刚好完全消除,只留下这个单独的数字。
那么解题也很简单了,就是把所有的数字挨个进行异或运算,我们不用在乎它的中间状态,只有一点可以确认:就是全部异或运算之后,只会留下单独的那个数字。
解题代码
func solution(cards []int) int {
result := 0
// 遍历数组中的每一个元素
for _, card := range cards {
// 将 result 与当前元素进行异或运算
result ^= card
}
return result
}
结语
以上便是本文的全部内容了,很高兴碰到这道题,让我对异或运算有了更深刻的理解。