898. Bitwise ORs of Subarrays

We have an array A of non-negative integers.

For every (contiguous) subarray B = [A[i], A[i+1], ..., A[j]] (with i <= j), we take the bitwise OR of all the elements in B, obtaining a result A[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. 1 <= A.length <= 50000
  2. 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/

永远渴望,大智若愚(stay hungry, stay foolish)
原文地址:https://www.cnblogs.com/h-hkai/p/10591923.html