From 703b9e49e7fd0d0f0b3c5187c202ab62e29fb9e9 Mon Sep 17 00:00:00 2001 From: CyC2018 Date: Fri, 30 Oct 2026 20:18:06 +0800 Subject: [PATCH] =?UTF-8?q?Update=2056.=20=E6=95=B0=E7=BB=84=E4=B8=AD?= =?UTF-8?q?=E5=8F=AA=E5=87=BA=E7=8E=B0=E4=B8=80=E6=AC=A1=E7=9A=84=E6=95=B0?= =?UTF-8?q?=E5=AD=97.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 精简并调整异或与分组求解思路的分步说明,补充具体的数组异或计算示例。 --- notes/56. 数组中只出现一次的数字.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/notes/56. 数组中只出现一次的数字.md b/notes/56. 数组中只出现一次的数字.md index a1a7be16..250ffbf1 100644 --- a/notes/56. 数组中只出现一次的数字.md +++ b/notes/56. 数组中只出现一次的数字.md @@ -10,11 +10,13 @@ ## 解题思路 -两个相等的元素异或的结果为 0,而 0 与任意数 x 异或的结果都为 x。 +两个相等的元素异或的结果为 0,而 0 与任意数 x 异或的结果都为 x。设只出现一次的两个数为 z 和 k: -对本题给的数组的所有元素执行异或操作,得到的是两个不存在重复的元素异或的结果。例如对于数组 [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。 +1. 对数组的所有元素执行异或操作,成对的元素相互抵消,得到 diff = z ^ k。z 和 k 不相等,diff 一定不为 0; +2. diff & -diff 取出 diff 最右侧为 1 的位,z 和 k 在这一位上一个为 0、一个为 1; +3. 按这一位是否为 1 把数组分成两组: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 异或的结果,也就是不相等两个元素本身。 +例如 [4, 1, 4, 6]:4 ^ 1 ^ 4 ^ 6 = 1 ^ 6 = 7(二进制 111),最右侧的 1 是最低位;最低位为 0 的 4、4、6 异或得 6,最低位为 1 的 1 异或得 1。 ```java public int[] sockCollocation(int[] sockets) {