zoukankan      html  css  js  c++  java
  • [LeetCode 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

    The O(N^2) brute force solution will cause TLE. So we need to optimize this somehow. If we try to count each A[i]'s contribution as the last element of a subarray and if we assume we can acheive this step efficiently, then we can solve this problem. In order to do this, we need to keep all the unique numbers contributed by the previous element A[i - 1] as the last subarray element. Why? Because we are only interested with continuous subarray.  If the contribution count of A[i - 1] is in order of O(N), we'll hit an dead end here. But is it? Since we are doing OR bitwise operation, if we consider A[i - 1] as the last subarray element and expand from right to left, then we'll have a strictly increasing sequence of unique numbers. Each number will have at least 1 more set bit that its predecessor in this sequence. There are only 32 bits in total, so this sequence can not be bigger than 32. Ahh haa! 

    Now the solution is pretty clear: 

    1. Keep a set of unique values seen so far, call it unique;

    2. Keep another set that stores all the unique numbers contributed by the previous element being the last subarray element, call it prev.

    3. For each new element, use the set in step2 to compute all the all the unique numbers contributed by the current element being the last subarray element, call it curr.

    4. add curr to unique and set prev to curr.

    class Solution {
        public int subarrayBitwiseORs(int[] A) {
            Set<Integer> unique = new HashSet<>();
            Set<Integer> prev = new HashSet<>();
            unique.add(A[0]);
            prev.add(A[0]);
            for(int i = 1; i < A.length; i++) {
                Set<Integer> curr = new HashSet<>();
                for(int v : prev) {
                    curr.add(v | A[i]);
                }
                curr.add(A[i]);
                unique.addAll(curr);
                prev = curr;
            }
            return unique.size();
        }
    }
  • 相关阅读:
    Java中常见数据结构:List与Map
    JAVA 双重检查锁定和延迟初始化
    Spring 读取配置文件(二)
    Spring 读取配置文件(一)
    Java配置文件读取和路径设置
    动态设置spring配置PropertyPlaceholderConfigurer location的路径
    MySQL 数据库备份种类以及经常使用备份工具汇总
    打印二叉树两个叶子节点间的路径
    读书报告之《改动代码的艺术》 (I)
    虚幻引擎自带的创建插件的插件
  • 原文地址:https://www.cnblogs.com/lz87/p/14088412.html
Copyright © 2011-2022 走看看