|
| 1 | +## 题目地址(1835. 所有数对按位与结果的异或和) |
| 2 | + |
| 3 | +https://leetcode-cn.com/problems/find-xor-sum-of-all-pairs-bitwise-and/ |
| 4 | + |
| 5 | +## 题目描述 |
| 6 | + |
| 7 | +``` |
| 8 | +列表的 异或和(XOR sum)指对所有元素进行按位 XOR 运算的结果。如果列表中仅有一个元素,那么其 异或和 就等于该元素。 |
| 9 | +
|
| 10 | +例如,[1,2,3,4] 的 异或和 等于 1 XOR 2 XOR 3 XOR 4 = 4 ,而 [3] 的 异或和 等于 3 。 |
| 11 | +
|
| 12 | +给你两个下标 从 0 开始 计数的数组 arr1 和 arr2 ,两数组均由非负整数组成。 |
| 13 | +
|
| 14 | +根据每个 (i, j) 数对,构造一个由 arr1[i] AND arr2[j](按位 AND 运算)结果组成的列表。其中 0 <= i < arr1.length 且 0 <= j < arr2.length 。 |
| 15 | +
|
| 16 | +返回上述列表的 异或和 。 |
| 17 | +
|
| 18 | + |
| 19 | +
|
| 20 | +示例 1: |
| 21 | +
|
| 22 | +输入:arr1 = [1,2,3], arr2 = [6,5] |
| 23 | +输出:0 |
| 24 | +解释:列表 = [1 AND 6, 1 AND 5, 2 AND 6, 2 AND 5, 3 AND 6, 3 AND 5] = [0,1,2,0,2,1] , |
| 25 | +异或和 = 0 XOR 1 XOR 2 XOR 0 XOR 2 XOR 1 = 0 。 |
| 26 | +
|
| 27 | +示例 2: |
| 28 | +
|
| 29 | +输入:arr1 = [12], arr2 = [4] |
| 30 | +输出:4 |
| 31 | +解释:列表 = [12 AND 4] = [4] ,异或和 = 4 。 |
| 32 | +
|
| 33 | +
|
| 34 | + |
| 35 | +
|
| 36 | +提示: |
| 37 | +
|
| 38 | +1 <= arr1.length, arr2.length <= 105 |
| 39 | +0 <= arr1[i], arr2[j] <= 109 |
| 40 | +``` |
| 41 | + |
| 42 | +## 前置知识 |
| 43 | + |
| 44 | +- 位运算 |
| 45 | + |
| 46 | +## 公司 |
| 47 | + |
| 48 | +- 暂无 |
| 49 | + |
| 50 | +## 思路 |
| 51 | + |
| 52 | +异或的性质:相同的位异或结果为 0 ,否则为 1。 |
| 53 | +AND 的性质:两个 1 AND 结果为 1,否则为 0 |
| 54 | + |
| 55 | +这道题需要我们返回 and 后异或的结果。更本质地,我们需要返回一个 32 bit 的数字。那么 32 位上分别是 0 还是 1 呢?这就是我们需要解决的问题。 |
| 56 | + |
| 57 | +而两个数组的异或和,实际上可以 **先** 生成一个长度为 m \* n 的数组,其中 m 和 n 分别为 A 和 B 的长度。 |
| 58 | + |
| 59 | +以题目的例子来说: |
| 60 | + |
| 61 | +``` |
| 62 | +输入:arr1 = [1,2,3], arr2 = [6,5] |
| 63 | +输出:0 |
| 64 | +解释:列表 = [1 AND 6, 1 AND 5, 2 AND 6, 2 AND 5, 3 AND 6, 3 AND 5] = [0,1,2,0,2,1] , |
| 65 | +``` |
| 66 | + |
| 67 | +列表长度就是 3 \* 2 = 6。 |
| 68 | + |
| 69 | +我们需要将这 m _ n 个数的 **逐位** 进行一次 XOR 操作,一共 XOR 32 次即可。每次 XOR 我们都需要将 m _ n 个数的 一共 m \* n 位参与运算。 |
| 70 | + |
| 71 | +具体来说,我们现在想确定**最终结果的第 i 位是 0 还是 1。由异或的性质,实际上只需要确定 m \* n 个数中第 i 位是 1 的个数即可。** |
| 72 | + |
| 73 | +- 如果 1 的个数是奇数,那么异或结果一定是 1 |
| 74 | +- 否则异或结果一定是 0 |
| 75 | + |
| 76 | +那么如果确定这 m _ n 个数的 1 的个数呢?这就需要用到上面提到的 AND 特性了。 1 只有和 1 结合才能搞出 1,因此我们只需要分别计算出 A 和 B 在这一位的 1 的个数即可,答案就是 A 和 B 在这一位的个数 **乘积** 。 比如 A 中在第 i 位 有 3 个 1,B 中在第 i 位有 4 个 1,那么 AND 后为 1 ,只能在这 3 _ 4 = 12 个 AND 中产生(笛卡尔积)。 |
| 77 | + |
| 78 | +## 关键点 |
| 79 | + |
| 80 | +- 从位的角度思考问题 |
| 81 | +- 位运算(这里是 AND 和 XOR)的基本特性 |
| 82 | + |
| 83 | +## 代码 |
| 84 | + |
| 85 | +- 语言支持:Python3 |
| 86 | + |
| 87 | +Python3 Code: |
| 88 | + |
| 89 | +```python |
| 90 | + |
| 91 | +class Solution: |
| 92 | + def getXORSum(self, A: List[int], B: List[int]) -> int: |
| 93 | + ans = 0 |
| 94 | + for i in range(31): |
| 95 | + ones_a = ones_b = 0 |
| 96 | + for a in A: |
| 97 | + if a & (1 << i): |
| 98 | + ones_a += 1 |
| 99 | + for b in B: |
| 100 | + if b & (1 << i): |
| 101 | + ones_b += 1 |
| 102 | + if ones_a * ones_b & 1: |
| 103 | + ans |= 1 << i |
| 104 | + return ans |
| 105 | + |
| 106 | +``` |
| 107 | + |
| 108 | +**复杂度分析** |
| 109 | + |
| 110 | +令 n 为数组长度。 |
| 111 | + |
| 112 | +- 时间复杂度:$O(32 * n)$ |
| 113 | +- 空间复杂度:$O(1)$ |
| 114 | + |
| 115 | +> 此题解由 [力扣刷题插件](https://leetcode-pp.github.io/leetcode-cheat/?tab=solution-template) 自动生成。 |
| 116 | +
|
| 117 | +力扣的小伙伴可以[关注我](https://leetcode-cn.com/u/fe-lucifer/),这样就会第一时间收到我的动态啦~ |
| 118 | + |
| 119 | +以上就是本文的全部内容了。大家对此有何看法,欢迎给我留言,我有时间都会一一查看回答。更多算法套路可以访问我的 LeetCode 题解仓库:https://github.com/azl397985856/leetcode 。 目前已经 40K star 啦。大家也可以关注我的公众号《力扣加加》带你啃下算法这块硬骨头。 |
| 120 | + |
| 121 | +关注公众号力扣加加,努力用清晰直白的语言还原解题思路,并且有大量图解,手把手教你识别套路,高效刷题。 |
| 122 | + |
| 123 | + |
0 commit comments