Bitwise ORs of Subarrays
MedPrompt
Given an integer array arr, return the number of distinct bitwise ORs of all the non-empty subarrays of arr.
The bitwise OR of a subarray is the bitwise OR of each integer in the subarray. The bitwise OR of a subarray of one integer is that integer.
A subarray is a contiguous non-empty sequence of elements within an array.
Example 1:
Input: arr = [0]
Output: 1
Explanation: There is only one possible result: 0.Example 2:
Input: arr = [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: arr = [1,2,4]
Output: 6
Explanation: The possible results are 1, 2, 3, 4, 6, and 7.
Constraints:
1 <= arr.length <= 5 * 1040 <= arr[i] <= 109
Approaches
2 approaches with complexity analysis and trade-offs.
This approach systematically finds every possible non-empty subarray, calculates its bitwise OR, and counts the number of unique results. A naive implementation would recompute the OR for each subarray from scratch, leading to an O(n^3) complexity. We can optimize this by observing that the OR of a subarray arr[i..j] is simply the OR of arr[i..j-1] and arr[j]. This allows us to compute the ORs for all subarrays starting at a given index i in a single pass, reducing the overall complexity.
Algorithm
-
- Initialize an empty
HashSetcalleddistinctOrsto store the unique bitwise OR values.
- Initialize an empty
-
- Iterate through the input array
arrwith an indexifrom0toarr.length - 1. This indexiwill be the starting point of our subarrays.
- Iterate through the input array
-
- Inside the first loop, initialize an integer
currentOrto0. This will store the bitwise OR of the subarray starting ati.
- Inside the first loop, initialize an integer
-
- Start a second, nested loop with an index
jfromitoarr.length - 1. This indexjwill be the ending point of our subarrays.
- Start a second, nested loop with an index
-
- In the inner loop, update
currentOrby performing a bitwise OR with the current element:currentOr |= arr[j].
- In the inner loop, update
-
- Add the
currentOrvalue to thedistinctOrsset. The set will only add the value if it's not already present.
- Add the
-
- After both loops complete, the
distinctOrsset contains all unique bitwise ORs of all possible subarrays.
- After both loops complete, the
-
- Return the size of the
distinctOrsset.
- Return the size of the
Walkthrough
We use two nested loops to iterate through all possible subarrays. The outer loop fixes the starting point i of the subarray, and the inner loop extends the subarray to the right by including elements from j = i to n-1.
A variable currentOr is used to maintain the bitwise OR of the current subarray arr[i..j]. As j increments, we update currentOr by taking the bitwise OR with the new element arr[j]. This avoids recalculating the OR from the beginning of the subarray each time.
All calculated currentOr values are stored in a HashSet to automatically handle uniqueness. The final answer is the size of this set.
import java.util.HashSet;import java.util.Set; class Solution { public int subarrayBitwiseORs(int[] arr) { Set<Integer> distinctOrs = new HashSet<>(); for (int i = 0; i < arr.length; i++) { int currentOr = 0; for (int j = i; j < arr.length; j++) { currentOr |= arr[j]; distinctOrs.add(currentOr); } } return distinctOrs.size(); }}Complexity
Time
`O(n^2)`, where `n` is the length of the array. The two nested loops iterate through all `n * (n + 1) / 2` subarrays, and the operation inside the inner loop is constant time.
Space
`O(D)`, where `D` is the number of distinct OR values. In the worst-case scenario, `D` can be on the order of `O(n^2)`, for example, if every subarray produces a unique OR value.
Trade-offs
Pros
Simple to understand and implement.
More efficient than the naive
O(n^3)approach.
Cons
The
O(n^2)time complexity is too slow for the given constraints (n <= 5 * 10^4), leading to a "Time Limit Exceeded" error on larger test cases.
Solutions
Solution
class Solution {public int subarrayBitwiseORs(int[] arr) { Set<Integer> s = new HashSet<>(); s.add(0); Set<Integer> ans = new HashSet<>(); for (int x : arr) { Set<Integer> t = new HashSet<>(); for (int y : s) { t.add(x | y); } t.add(x); s = t; ans.addAll(s); } return ans.size(); }}Video walkthrough
Newsletter
One sharp idea, every week
System design and interview prep — short enough to finish.
No spam. Unsubscribe anytime.
Practice
Same difficulty — related problems to reinforce the pattern.