问题描述
在一个班级中,每位同学都拿到了一张卡片,上面有一个整数。有趣的是,除了一个数字之外,所有的数字都恰好出现了两次。现在需要你帮助班长小C快速找到那个拿了独特数字卡片的同学手上的数字是什么。
使用算法
异或的性质
- 交换律:a ⊕ b = b ⊕ a。这意味着异或运算不依赖于操作数的顺序。
- 结合律:a ⊕ (b ⊕ c) = (a ⊕ b) ⊕ c。这表明在进行多个数的异或运算时,可以任意分组而不影响结果。
- 恒等律:任何数与0进行异或运算结果仍然是原数,即 x ⊕ 0 = x。
- 归零律:任何数与自身进行异或运算结果为0,即 x ⊕ x = 0。
- 自反性:a ⊕ b ⊕ b = a。这意味着如果一个数与另一个数异或后再与同一个数异或,结果会还原为原数。
- 逆元:对于任何布尔值a,有 a ⊕ 0 = a 与 a ⊕ a = 0,即对于异或操作,每一个布尔值a的逆元就是它本身。
算法思路
-
初始化异或结果:
- 定义一个变量
xor,初始值为0。这个变量将用来存储异或的结果。
- 定义一个变量
-
遍历数组进行异或运算:
- 遍历数组
cards中的每一个元素card。 - 对于每个元素,将其与
xor变量进行异或运算,并将结果赋值回xor变量。
- 遍历数组
-
利用异或运算的性质:
- 异或运算有一个重要的性质:任何数和0进行异或运算,结果仍然是这个数;任何数和其自身进行异或运算,结果是0。
- 因此,如果一个数字在数组中出现了两次,那么这两个相同的数字进行异或运算的结果将是0。
- 如果一个数字只出现一次,那么它与任何其他数字(包括0)进行异或运算的结果仍然是它自己。
-
得出结果:
- 遍历完整个数组后,
xor变量中存储的就是那个只出现一次的数字,因为所有成对出现的数字在异或运算中都被抵消了。
- 遍历完整个数组后,
-
返回结果:
solution函数返回xor变量的值,即那个独特的数字。
public class Main {
public static int solution(int[] cards) {
// Edit your code here
int xor = 0;
for(int card: cards){
xor ^= card;
}
return xor;
}
public static void main(String[] args) {
// Add your test cases here
System.out.println(solution(new int[] { 1, 1, 2, 2, 3, 3, 4, 5, 5 }) == 4);
System.out.println(solution(new int[] { 0, 1, 0, 1, 2 }) == 2);
}
}