解题思路细化
-
理解按位与操作:
- 按位与操作
&是对两个数的二进制表示的每一位进行与操作。只有当两个数的对应位都为1时,结果的对应位才为1,否则为0。 - 因此,
nums[i] & nums[j] & nums[k] == 0意味着这三个数的二进制表示中,每一位上至少有一个数为0。
- 按位与操作
-
数据结构的选择:
- 我们可以使用一个二维数组
andResults来存储所有可能的nums[i] & nums[j]的结果。 - 然后,我们遍历所有可能的三元组
(i, j, k),检查andResults[i][j] & nums[k]是否为0。
- 我们可以使用一个二维数组
-
算法步骤:
- Step 1: 计算所有可能的
nums[i] & nums[j]的结果,并存储在andResults数组中。 - Step 2: 遍历所有可能的三元组
(i, j, k),检查andResults[i][j] & nums[k]是否为0,如果是,则计数器加1。
- Step 1: 计算所有可能的
public class Main {
public static int solution(int[] nums) {
int n = nums.length;
int[][] andResults = new int[n][n];
// Step 1: Calculate pairwise AND results
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
andResults[i][j] = nums[i] & nums[j];
}
}
// Step 2: Count valid triplets
int count = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
for (int k = 0; k < n; k++) {
if ((andResults[i][j] & nums[k]) == 0) {
count++;
}
}
}
}
return count;
}
public static void main(String[] args) {
System.out.println(solution(new int[]{2, 1, 3}) == 12 ? 1 : 0);
System.out.println(solution(new int[]{0, 2, 5}) == 25 ? 1 : 0);
System.out.println(solution(new int[]{1, 2, 4}) == 24 ? 1 : 0);
}
}
关键步骤
- Step 1: 计算所有可能的
nums[i] & nums[j]的结果,并存储在andResults数组中。 - Step 2: 遍历所有可能的三元组
(i, j, k),检查andResults[i][j] & nums[k]是否为0,如果是,则计数器加1
关键步骤提示
-
Step 1: 计算所有可能的
nums[i] & nums[j]的结果,并存储在andResults数组中。- 这一步的目的是为了减少后续计算的复杂度,因为我们可以预先计算出所有可能的
nums[i] & nums[j]的结果。
- 这一步的目的是为了减少后续计算的复杂度,因为我们可以预先计算出所有可能的
-
Step 2: 遍历所有可能的三元组
(i, j, k),检查andResults[i][j] & nums[k]是否为0,如果是,则计数器加1。- 这一步的目的是找到所有满足条件的三元组。我们可以通过遍历所有可能的三元组来实现这一点。
优化建议
- 当前的算法时间复杂度为
O(n^3),对于较大的数组可能会比较慢。可以考虑使用位运算的特性来优化,例如使用位掩码来快速判断是否存在满足条件的三元组。