CS-Notes/notes/56. 数组中只出现一次的数字.md
2021-03-23 02:48:19 +08:00

46 lines
2.1 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 56. 数组中只出现一次的数字
## 题目链接
[牛客网](https://www.nowcoder.com/practice/389fc1c3d3be4479a154f63f495abff8?tpId=13&tqId=11193&tab=answerKey&from=cyc_github)
## 题目描述
一个整型数组里除了两个数字之外其他的数字都出现了两次找出这两个数
## 解题思路
两个相等的元素异或的结果为 0 0 与任意数 x 异或的结果都为 x
对本题给的数组的所有元素执行异或操作得到的是两个不存在重复的元素异或的结果例如对于数组 [x,x,y,y,z,k]x^x^y^y^z^k = 0^y^y^z^k = y^y^z^k = 0^z^k = z^k
两个不相等的元素在位级表示上一定会有所不同因此这两个元素异或得到的结果 diff 一定不为 0位运算 diff & -diff 能得到 diff 位级表示中最右侧为 1 的位 diff = diff & -diff diff 作为区分两个元素的依据一定有一个元素对 diff 进行异或的结果为 0另一个结果非 0设不相等的两个元素分别为 z k遍历数组所有元素判断元素与 diff 的异或结果是否为 0如果是的话将元素与 z 进行异或并赋值给 z否则与 k 进行异或并赋值给 k数组中相等的元素一定会同时与 z 或者与 k 进行异或操作而不是一个与 z 进行异或一个与 k 进行异或而且这些相等的元素异或的结果为 0因此最后 z k 只是不相等的两个元素与 0 异或的结果也就是不相等两个元素本身
下面的解法中num1 num2 数组的第一个元素是用来保持返回值的... 实际开发中不推荐这种返回值的方式
```java
public int[] FindNumsAppearOnce (int[] nums) {
int[] res = new int[2];
int diff = 0;
for (int num : nums)
diff ^= num;
diff &= -diff;
for (int num : nums) {
if ((num & diff) == 0)
res[0] ^= num;
else
res[1] ^= num;
}
if (res[0] > res[1]) {
swap(res);
}
return res;
}
private void swap(int[] nums) {
int t = nums[0];
nums[0] = nums[1];
nums[1] = t;
}
```