给你一个整数数组 nums ,返回其中 按位与三元组 的数目。
按位与三元组 是由下标 (i, j, k) 组成的三元组,并满足下述全部条件:
0 <= i < nums.length
0 <= j < nums.length
0 <= k < nums.length
nums[i] & nums[j] & nums[k] == 0 ,其中 & 表示按位与运算符。
示例 1:
输入:nums = [2,1,3]
输出:12
解释:可以选出如下 i, j, k 三元组:
(i=0, j=0, k=1) : 2 & 2 & 1
(i=0, j=1, k=0) : 2 & 1 & 2
(i=0, j=1, k=1) : 2 & 1 & 1
(i=0, j=1, k=2) : 2 & 1 & 3
(i=0, j=2, k=1) : 2 & 3 & 1
(i=1, j=0, k=0) : 1 & 2 & 2
(i=1, j=0, k=1) : 1 & 2 & 1
(i=1, j=0, k=2) : 1 & 2 & 3
(i=1, j=1, k=0) : 1 & 1 & 2
(i=1, j=2, k=0) : 1 & 3 & 2
(i=2, j=0, k=1) : 3 & 2 & 1
(i=2, j=1, k=0) : 3 & 1 & 2
示例 2:
输入:nums = [0,0,0]
输出:27
提示:
1 <= nums.length <= 1000
0 <= nums[i] < 216
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/triples-with-bitwise-and-equal-to-zero
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
感觉这道题没啥意思。最简单的解法是直接上三重for循环,时间复杂度达到了n^3,指定挂。可以利用额外空间来存储两个数相与的结果,可以降低一重复杂度,但这样如果可以过的话,也顶多中等题的难度。再优的解法是快速沃尔什变换,复杂度 O(n+ClogC),但明显超纲严重。
一开始想用哈希表来存储两个数相与的结果并计数,但由于a&b = c,无法仅通过c 和a 推出b,只能作罢,转而直接利用数组来存储。(哈希表的构建遍历也挺费时间的,如果需要遍历哈希表的键来判断的话,效率大概率不会比直接用数组存储好)。
代码如下:
class Solution { public int countTriplets(int[] nums) { int[] arr = new int[1 << 16]; for (int x : nums) { for (int y : nums) { arr[x & y] ++; } } int ans = 0; for (int x : nums) { for (int mask = 0; mask < (1 << 16); ++mask) { if ((x & mask) == 0) { ans += arr[mask]; } } } return ans; } }