[LeetCode] 898. Bitwise ORs of Subarrays 子數組按位或操做



We have an array A of non-negative integers.html

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].git

Return the number of possible results.  (Results that occur more than once are only counted once in the final answer.)github

Example 1:數組

Input: [0]
Output: 1
Explanation:
There is only one possible result: 0.

Example 2:code

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:htm

Input: [1,2,4]
Output: 6
Explanation:
The possible results are 1, 2, 3, 4, 6, and 7.

Note:blog

  1. 1 <= A.length <= 50000
  2. 0 <= A[i] <= 10^9



這是一道蠻有意思的題目,說是給了咱們一個數組,裏面都是非負數,問咱們全部連續的子數組'或'起來能產生多少個不一樣的值。雖然說這只是一道 Medium 的題,可是直覺告訴博主,暴力遍歷全部子數組,而且一個一個的'或'將會產生大量的重複運算,不出意外應該是會 TLE 的。因此博主的第一直覺是能不能創建相似累加和同樣的數組,而後快速計算任意區間的總'或'值,嘗試了一下,雖然能夠創建累加'或'數組,可是沒法獲得正確的區間總'或'值,博主甚至嘗試了'異或',仍然不對,只得做罷。其實這道題的正確解法仍是蠻巧妙的,感受不容易一會兒想到,這裏主要參考了 網上大神 zhoubowei 的帖子,舉個例子吧,好比數組 [0, 3, 4, 6, 5],寫成二進制的就是 [001, 011, 100, 110, 101],生成子數組的方法跟生成子集合 Subsets 有些相似,但因爲子數組必須是連續的,因此個數比子集合要少一些,生成的方法也是在現有的集合都加入當前數字,並每次新加一個只有當前數字的集合,順序以下:element

[001]
[001 011] [011]
[001 011 100] [011 100] [100]
[001 011 100 110] [011 100 110] [100 110] [110]
[001 011 100 110 101] [011 100 110 101] [100 110 101] [110 101] [101]

咱們能夠看到,最開始就只有一個集合 [001],而後對於數字 011,先放到現有集合中,變成 [001 011],而後再新建一個本身的集合 [011],對於後面的數字都是一樣的操做,最後咱們就有5個不一樣的集合,表明了全部的子數組,咱們對每一個集合都計算總'或'值,能夠獲得:leetcode

001
011 011
111 111 100
111 111 110 110
111 111 111 111 101

以前提到了,若對於每一個集合都一個一個的'或'起來,將會十分的不高效,而其實這裏面可能會有許多重複值,因此對重複值只須要保留一個,實際上就能夠變成:get

001
011
111 100
111 110
111 101

這樣數字就減小了不少,使得計算效率也就大大的提升了。具體的作法是,開始先創建兩個 HashSet,分別是 res 和 cur,而後遍歷數組A,對於每一個遍歷到的數字,首先生成一個本身的集合 tmp,而後遍歷集合 cur 中的全部數字,將當前數字和 cur 中的每一個數字相'或',並存入 tmp 中,因爲 HashSet 能夠自動去重複,因此 tmp 中保存的只有不一樣的值,而後將 tmp 所有賦值給 cur,再將 cur 中的全部值加入結果 res 中,因爲結果 res 也是 HashSet,也能夠自動去重複,最後留在 res 中的就是全部不一樣的子數組的總'或'值,參見代碼以下:


class Solution {
public:
    int subarrayBitwiseORs(vector<int>& A) {
        unordered_set<int> res, cur;
        for (int i : A) {
            unordered_set<int> tmp = {i};
            for (int j : cur) tmp.insert(i | j);
            cur = tmp;
            for (int j : cur) res.insert(j);
        }
        return res.size();
    }
};



Github 同步地址:

https://github.com/grandyang/leetcode/issues/898



參考資料:

https://leetcode.com/problems/bitwise-ors-of-subarrays/

https://leetcode.com/problems/bitwise-ors-of-subarrays/discuss/165859/C%2B%2B-O(kN)-solution

https://leetcode.com/problems/bitwise-ors-of-subarrays/discuss/165881/C%2B%2BJavaPython-O(30N)



LeetCode All in One 題目講解彙總(持續更新中...)

相關文章
相關標籤/搜索