文章目录
- 题目
- 标题和出处
- 难度
- 题目描述
- 要求
- 示例
- 数据范围
- 解法一
- 思路和算法
- 代码
- 复杂度分析
- 解法二
- 思路和算法
- 代码
- 复杂度分析
题目
标题和出处
标题:形成两个异或相等数组的三元组数目
出处:1442. 形成两个异或相等数组的三元组数目
难度
5 级
题目描述
要求
给定一个整数数组 arr \texttt{arr} arr。
现需要从数组中取三个下标 i \texttt{i} i、 j \texttt{j} j 和 k \texttt{k} k,其中 0 ≤ i < j ≤ k < arr.length \texttt{0} \le \texttt{i} < \texttt{j} \le \texttt{k} < \texttt{arr.length} 0≤i<j≤k<arr.length。
定义 a \texttt{a} a 和 b \texttt{b} b 如下:
- a = arr[i] ⊕ arr[i + 1] ⊕ … ⊕ arr[j - 1] \texttt{a} = \texttt{arr[i]} \oplus \texttt{arr[i + 1]} \oplus \ldots \oplus \texttt{arr[j - 1]} a=arr[i]⊕arr[i + 1]⊕…⊕arr[j - 1]
- b = arr[j] ⊕ arr[j + 1] ⊕ … ⊕ arr[k] \texttt{b} = \texttt{arr[j]} \oplus \texttt{arr[j + 1]} \oplus \ldots \oplus \texttt{arr[k]} b=arr[j]⊕arr[j + 1]⊕…⊕arr[k]
⊕ \oplus ⊕ 表示按位异或操作。
返回使 a = b \texttt{a} = \texttt{b} a=b 成立的三元组 (i, j, k) \texttt{(i, j, k)} (i, j, k) 的数目。
示例
示例 1:
输入: arr = [2,3,1,6,7] \texttt{arr = [2,3,1,6,7]} arr = [2,3,1,6,7]
输出: 4 \texttt{4} 4
解释:满足题意的三元组分别是 (0,1,2) \texttt{(0,1,2)} (0,1,2)、 (0,2,2) \texttt{(0,2,2)} (0,2,2)、 (2,3,4) \texttt{(2,3,4)} (2,3,4) 和 (2,4,4) \texttt{(2,4,4)} (2,4,4)。
示例 2:
输入: arr = [1,1,1,1,1] \texttt{arr = [1,1,1,1,1]} arr = [1,1,1,1,1]
输出: 10 \texttt{10} 10
数据范围
- 1 ≤ arr.length ≤ 300 \texttt{1} \le \texttt{arr.length} \le \texttt{300} 1≤arr.length≤300
- 1 ≤ arr[i] ≤ 10 8 \texttt{1} \le \texttt{arr[i]} \le \texttt{10}^\texttt{8} 1≤arr[i]≤108
解法一
思路和算法
对于选定的三个下标 i i i、 j j j 和 k k k,其中 i < j ≤ k i < j \le k i<j≤k, a a a 等于数组 arr \textit{arr} arr 的下标范围 [ i , j − 1 ] [i, j - 1] [i,j−1] 中的所有元素的按位异或运算结果, b b b 等于数组 arr \textit{arr} arr 的下标范围 [ j , k ] [j, k] [j,k] 中的所有元素的按位异或运算结果,因此 a ⊕ b a \oplus b a⊕b 等于数组 arr \textit{arr} arr 的下标范围 [ i , k ] [i, k] [i,k] 中的所有元素的按位异或运算结果。
根据按位异或运算的性质, a = b a = b a=b 等价于 a ⊕ b = 0 a \oplus b = 0 a⊕b=0。如果数组 arr \textit{arr} arr 的下标范围 [ i , k ] [i, k] [i,k] 中的所有元素的按位异或运算结果等于 0 0 0,则对于任意满足 i < j ≤ k i < j \le k i<j≤k 的下标 j j j 都有 a ⊕ b = 0 a \oplus b = 0 a⊕b=0,等价于 a = b a = b a=b,因此在确定 i i i 和 k k k 的情况下, j j j 可以取 i + 1 i + 1 i+1 到 k k k 的任意下标,有 k − i k - i k−i 种取值。
为了计算符合要求的三元组的数目,需要遍历数组 arr \textit{arr} arr 的所有子数组,对于每个子数组计算子数组中的所有元素的按位异或运算结果。如果一个下标范围是 [ i , k ] [i, k] [i,k] 的子数组中的所有元素的按位异或运算结果等于 0 0 0,则该子数组中符合要求的三元组的数目是 k − i k - i k−i,将该数目加到答案中。遍历全部子数组之后,即可得到符合要求的三元组的数目。
代码
class Solution {public int countTriplets(int[] arr) {int count = 0;int length = arr.length;for (int i = 0; i < length; i++) {for (int k = i + 1; k < length; k++) {int xor = 0;for (int j = i; j <= k; j++) {xor ^= arr[j];}if (xor == 0) {count += k - i;}}}return count;}
}
复杂度分析
-
时间复杂度: O ( n 3 ) O(n^3) O(n3),其中 n n n 是数组 arr \textit{arr} arr 的长度。数组 arr \textit{arr} arr 的子数组个数是 O ( n 2 ) O(n^2) O(n2),对于每个子数组需要 O ( n ) O(n) O(n) 的时间计算子数组中的所有元素的按位异或运算结果,因此时间复杂度是 O ( n 3 ) O(n^3) O(n3)。
-
空间复杂度: O ( 1 ) O(1) O(1)。
解法二
思路和算法
解法一当中对于每个子数组计算所有元素的按位异或运算结果需要 O ( n ) O(n) O(n) 的时间,可以将计算按位异或运算结果的时间降低到 O ( 1 ) O(1) O(1)。
当子数组的开始下标 i i i 确定时,每个大于等于 i i i 的下标 k k k 都可以作为子数组的结束下标。假设下标范围 [ i , k − 1 ] [i, k - 1] [i,k−1] 对应的按位异或运算结果是 xor \textit{xor} xor,则下标范围 [ i , k ] [i, k] [i,k] 对应的按位异或运算结果等于 xor ⊕ arr [ k ] \textit{xor} \oplus \textit{arr}[k] xor⊕arr[k]。使用该方法,计算一个子数组中的所有元素的按位异或运算结果的时间是 O ( 1 ) O(1) O(1)。
代码
class Solution {public int countTriplets(int[] arr) {int count = 0;int length = arr.length;for (int i = 0; i < length; i++) {int xor = 0;for (int k = i; k < length; k++) {xor ^= arr[k];if (xor == 0) {count += k - i;}}}return count;}
}
复杂度分析
-
时间复杂度: O ( n 2 ) O(n^2) O(n2),其中 n n n 是数组 arr \textit{arr} arr 的长度。数组 arr \textit{arr} arr 的子数组个数是 O ( n 2 ) O(n^2) O(n2),对于每个子数组计算子数组中的所有元素的按位异或运算结果的时间是 O ( 1 ) O(1) O(1),因此时间复杂度是 O ( n 2 ) O(n^2) O(n2)。
-
空间复杂度: O ( 1 ) O(1) O(1)。