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/