We have an array
A
of non-negative integers.For every (contiguous) subarray
B = [A[i], A[i+1], ..., A[j]]
(withi <= j
), we take the bitwise OR of all the elements inB
, obtaining a resultA[i] | A[i+1] | ... | A[j]
.Return the number of possible results. (Results that occur more than once are only counted once in the final answer.)
Example 1:
Input: [0] Output: 1 Explanation: There is only one possible result: 0.
Example 2:
Input: [1,1,2] Output: 3 Explanation: The possible subarrays are [1], [1], [2], [1, 1], [1, 2], [1, 1, 2]. These yield the results 1, 1, 2, 1, 3, 3. There are 3 unique values, so the answer is 3.
Example 3:
Input: [1,2,4] Output: 6 Explanation: The possible results are 1, 2, 3, 4, 6, and 7.
Note:
1 <= A.length <= 50000
0 <= A[i] <= 10^9
Approach #1: Brute force. [C++] [TEL]
int subarrayBitwiseORs1(vector<int>& A) {
int len = A.size();
set<int> ans;
for (int i = 0; i < len; ++i) {
for (int j = i; j < len; ++j) {
int temp = 0;
for (int k = i; k <= j; ++k) {
temp |= A[k];
}
ans.insert(temp);
}
}
return ans.size();
}
Approach #2: DP[ ][ ]. [C++] [TEL]
int subarrayBitwiseORs2(vector<int>& A) {
int len = A.size();
unordered_set<int> ans(begin(A), end(A));
vector<vector<int>> dp(len, vector<int>(len));
for (int l = 1; l <= len; ++l) {
for (int i = 0; i <= len - l; ++i) {
int j = i + l - 1;
if (l == 1) {
dp[i][j] = A[j];
continue;
}
dp[i][j] = dp[i][j-1] | A[j];
ans.insert(dp[i][j]);
}
}
return ans.size();
}
Approach #3: DP[ ]. [C++] [TEL]
int subarrayBitwiseORs3(vector<int>& A) {
int len = A.size();
unordered_set<int> ans(begin(A), end(A));
vector<int> dp(A);
for (int l = 2; l <= len; ++l) {
for (int i = 0; i <= len - l; ++i) {
ans.insert(dp[i] |= A[i+l-1]);
}
}
return ans.size();
}
dp[i][j] = dp[i] | dp[i+1] | ..... | dp[j]
dp[i][j] = dp[i][j-1] | A[j]
ans = len(set(dp))
Time complexity: O(n^2)
Space complexity: O(n^2) -> O(n)
Approach #4: DP + Bit. [C++]
int subarrayBitwiseORs(vector<int>& A) {
unordered_set<int> ans;
unordered_set<int> cur;
unordered_set<int> nxt;
for (int a : A) {
nxt.clear();
nxt.insert(a);
for (int c : cur) {
nxt.insert(c | a);
}
cur.swap(nxt);
ans.insert(begin(cur), end(cur));
}
return ans.size();
}
Approach #5: DP + Bit. [Java]
public int subarrayBitwiseORs(int[] A) {
Set<Integer> ans = new HashSet<>();
Set<Integer> cur = new HashSet<>();
for (int a : A) {
Set<Integer> nxt = new HashSet<>();
nxt.add(a);
for (int b : cur) {
nxt.add(b | a);
}
ans.addAll(nxt);
cur = nxt;
}
return ans.size();
}
Approach #6: DP + Bit. [Python]
class Solution(object):
def subarrayBitwiseORs(self, A):
"""
:type A: List[int]
:rtype: int
"""
cur = set()
ans = set()
for a in A:
cur = {a | b for b in cur} | {a}
ans |= cur
return len(ans)
Analysis:
Reference:
https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-898-bitwise-ors-of-subarrays/