Given an array of integers A, find the number of triples of indices (i, j, k)
such that:
0 <= i < A.length
0 <= j < A.length
0 <= k < A.length
A[i] & A[j] & A[k] == 0, where & represents the bitwise-AND operator.
Example 1:
Input: [2,1,3]
Output: 12
Explanation: We could choose the following i, j, k triples:
(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
Note:
1 <= A.length <= 1000
0 <= A[i] < 2^16
题意:给出一个数组,求数组中有多少三元组相与为0,数组的数可以重复用。
解法一:先遍历两个数相与的所用结果,使用map<a, b> 存储相与为a的有多少个,然后再遍历第三个元素和map里的再相与。
class Solution {
public:
int countTriplets(vector<int>& A) {
int n = A.size();
int ans = 0;
map<int, int> m;
for(int i = 0; i < n; ++i){
for(int j = 0; j < n; ++j){
m[A[i] & A[j]]++;
}
}
for(int i = 0; i < n; ++i){
for(auto b : m){
if((A[i] & b.first) == 0)
ans += b.second;
}
}
return ans;
}
};
解法二:https://leetcode.com/problems/triples-with-bitwise-and-equal-to-zero/discuss/227309/C%2B%2B-naive-O(n-*-n)
如果我们知道输入很大,我们可以使用数组而不是哈希集。该数组的大小为1<<16。这将大大加快速度。
class Solution {
public:
int countTriplets(vector<int>& A) {
int ans = 0;
int tuples[1 << 16] = {};
for(auto a : A)
for(auto b : A)
tuples[a & b]++;
for(auto a : A)
for(auto i = 0; i < (1 << 16) ; ++i)
if((i & a) == 0)
ans += tuples[i];
return ans;
}
};