按位与为零的三元组【LC982】
给你一个整数数组
nums
,返回其中 按位与三元组 的数目。按位与三元组 是由下标
(i, j, k)
组成的三元组,并满足下述全部条件:
0 <= i < nums.length
0 <= j < nums.length
0 <= k < nums.length
nums[i] & nums[j] & nums[k] == 0
,其中&
表示按位与运算符。
先就这样 晚上要考试 好焦虑
-
思路:
- 暴力枚举的时间复杂度是 O ( n 3 ) O(n^3) O(n3),可以使用哈希表优化时间复杂度,类似四数之和
- 使用哈希表记录所有二元组相与后的结果出现的次数,然后枚举
nums[k]
和哈希表的key值,如果相与后结果为0,那么将二元组出现的次数累加至结果中
-
实现
class Solution { public int countTriplets(int[] nums) { int ans = 0; int n = nums.length; Map<Integer, Integer> map = new HashMap<>(); for (int i = 0; i < n; i++){ for (int j = 0; j < n; j++){ int tmp = (nums[i] & nums[j]); map.put(tmp, map.getOrDefault(tmp, 0) + 1); } } for (int num : nums){ for (int m = 0; m < (1 << 16); m++){ if ((m & num) == 0){ ans += map.getOrDefault(m, 0); } } } return ans; } }
- 复杂度
- 时间复杂度: O ( n 2 + C ∗ n ) O(n^2+C*n) O(n2+C∗n),n为数组长度, C C C为结果集的大小,本题中为 C = 2 16 C=2^{16} C=216
- 空间复杂度: O ( C ) O(C) O(C)
- 复杂度
-
优化:枚举的起点
考完试补