1442. 形成两个异或相等数组的三元组数目
大约 3 分钟
---
1442. 形成两个异或相等数组的三元组数目
- 标签:位运算、数组、哈希表、数学
- 难度:中等
题目链接
题目大意
描述:给定一个整数数组 。选择三个下标 ,满足 。
定义:
要求:返回满足 的三元组 的数量。
说明:
- 。
- 。
示例:
- 示例 1:
输入:arr = [2,3,1,6,7]
输出:4
解释:满足题意的三元组分别是 (0,1,2), (0,2,2), (2,3,4) 以及 (2,4,4)- 示例 2:
输入:arr = [1,1,1,1,1]
输出:10解题思路
思路 1:异或性质 + 哈希优化
1. 核心思想
根据异或运算的性质, 等价于 ,即:
此时对于任意满足条件的 (),都有 。
因此问题转化为:找下标对 (),使得 。对于每个满足条件的 ,有 个可行的 。
2. 具体步骤
第 1 步:计算前缀异或。定义 ,则 。
第 2 步:条件 等价于 。
第 3 步:遍历 和 (),如果 ,则 。
第 4 步:可以进一步优化为 哈希法。
3. 举例说明
以 为例:
满足 的对:
- : → 个三元组
- (但 ,实际 ): → 实际
思路 1:代码
class Solution:
def countTriplets(self, arr: List[int]) -> int:
n = len(arr)
prefix = [0] * (n + 1)
for i in range(n):
prefix[i + 1] = prefix[i] ^ arr[i]
ans = 0
for i in range(n):
for k in range(i + 1, n):
if prefix[i] == prefix[k + 1]:
ans += (k - i)
return ans思路 1:复杂度分析
- 时间复杂度:。
- 空间复杂度:。
思路 2:哈希表优化到
class Solution:
def countTriplets(self, arr: List[int]) -> int:
n = len(arr)
# count[x] 表示前缀异或值为 x 出现的次数
# total[x] 表示前缀异或值为 x 的索引和
count = {0: 1}
total = {0: 0}
prefix = 0
ans = 0
for k in range(n):
prefix ^= arr[k]
# 如果 prefix 之前出现过,设上次出现位置为 i-1
# 则 arr[i...k] 的异或和为 0
# 对于每个出现位置 i-1,j 可以取 i...k 中的任意值,贡献 k-i+1
# 用 count 和 total 累计
if prefix in count:
# j 可选的个数 = k * count[prefix] - total[prefix]
ans += k * count[prefix] - total[prefix]
count[prefix] += 1
total[prefix] += k + 1
else:
count[prefix] = 1
total[prefix] = k + 1
return ans哈希法巧妙地将 优化为 。