Skip to content

Commit 252f701

Browse files
Add solution for LeetCode #898: Bitwise ORs of Subarrays
1 parent 8568a5a commit 252f701

File tree

3 files changed

+178
-0
lines changed

3 files changed

+178
-0
lines changed
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
# Bitwise ORs of Subarrays - Problem #898
2+
3+
## Problem Statement
4+
We have an array `arr` of non-negative integers.
5+
6+
For every (contiguous) subarray `sub = [arr[i], arr[i + 1], ..., arr[j]]` (with `i <= j`), we take the bitwise OR of all the numbers in `sub`, obtaining a result `arr[i] | arr[i + 1] | ... | arr[j]`.
7+
8+
Return the number of possible results. Results that occur more than once are only counted once in the final answer.
9+
10+
## Examples
11+
```
12+
Input: arr = [0]
13+
Output: 1
14+
Explanation: There is only one possible result: 0.
15+
16+
Input: arr = [1,1,2]
17+
Output: 3
18+
Explanation: The possible subarrays are [1], [1], [2], [1,1], [1,2], [1,1,2].
19+
These yield the results 1, 1, 2, 1, 3, 3.
20+
There are 3 unique values, so the answer is 3.
21+
22+
Input: arr = [1,2,4]
23+
Output: 6
24+
Explanation: The possible results are 1, 2, 3, 4, 6, and 7.
25+
```
26+
27+
## Approach
28+
**Key Insight**: The number of unique bitwise OR results is much smaller than the number of possible subarrays because:
29+
1. Bitwise OR is monotonic - adding more elements can only increase or keep the same value
30+
2. There are only 32 possible bits in an integer, so the number of unique results is bounded
31+
32+
**Algorithm**:
33+
1. For each position in the array, maintain a set of all possible bitwise OR values that can be achieved by subarrays ending at that position
34+
2. For each new element, compute the bitwise OR with all previous results
35+
3. Use a HashSet to track all unique results across all positions
36+
37+
**Why this works**:
38+
- We don't need to check all possible subarrays explicitly
39+
- We can build the results incrementally by extending subarrays from each position
40+
- The monotonicity of bitwise OR means we can efficiently track all possible values
41+
42+
## Complexity Analysis
43+
- **Time Complexity**: O(n * 32) = O(n) - Each element can contribute at most 32 unique bitwise OR values
44+
- **Space Complexity**: O(32) = O(1) - We only need to store at most 32 unique values at any time
45+
46+
## Key Insights
47+
- Bitwise OR is monotonic: a | b ≥ max(a, b)
48+
- The number of unique bitwise OR results is bounded by the number of bits (32 for integers)
49+
- We can efficiently track all possible results by building them incrementally
50+
- Each new element can only create new results by OR-ing with existing results
51+
52+
## Alternative Approaches
53+
1. **Brute Force**: Check all possible subarrays - O(n²) time, but still efficient due to bounded unique results
54+
2. **Dynamic Programming**: Can be viewed as a DP problem where we track all possible OR values at each position
55+
56+
## Solutions in Different Languages
57+
58+
### Java
59+
```java
60+
// See solution.java
61+
class Solution {
62+
public int subarrayBitwiseORs(int[] arr) {
63+
Set<Integer> result = new HashSet<>();
64+
Set<Integer> current = new HashSet<>();
65+
66+
for (int num : arr) {
67+
Set<Integer> next = new HashSet<>();
68+
next.add(num);
69+
70+
for (int val : current) {
71+
next.add(val | num);
72+
}
73+
74+
result.addAll(next);
75+
current = next;
76+
}
77+
78+
return result.size();
79+
}
80+
}
81+
```
82+
83+
### JavaScript
84+
```javascript
85+
// See solution.js
86+
/**
87+
* @param {number[]} arr
88+
* @return {number}
89+
*/
90+
var subarrayBitwiseORs = function(arr) {
91+
const result = new Set();
92+
let current = new Set();
93+
94+
for (const num of arr) {
95+
const next = new Set();
96+
next.add(num);
97+
98+
for (const val of current) {
99+
next.add(val | num);
100+
}
101+
102+
for (const val of next) {
103+
result.add(val);
104+
}
105+
106+
current = next;
107+
}
108+
109+
return result.size();
110+
};
111+
```
112+
113+
## Test Cases
114+
```
115+
Test Case 1: [0] → 1
116+
Test Case 2: [1,1,2] → 3
117+
Test Case 3: [1,2,4] → 6
118+
Test Case 4: [1,2,3] → 4
119+
Test Case 5: [1,1,1,1] → 1
120+
```
121+
122+
## Edge Cases
123+
- Single element arrays
124+
- Arrays with all same elements
125+
- Arrays with large numbers
126+
- Empty arrays (though not mentioned in constraints)
127+
128+
## Related Problems
129+
- Subarray Sum Equals K
130+
- Bitwise AND of Numbers Range
131+
- Maximum XOR of Two Numbers in an Array
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import java.util.*;
2+
3+
class Solution {
4+
public int subarrayBitwiseORs(int[] arr) {
5+
Set<Integer> result = new HashSet<>();
6+
Set<Integer> current = new HashSet<>();
7+
8+
for (int num : arr) {
9+
Set<Integer> next = new HashSet<>();
10+
next.add(num);
11+
12+
for (int val : current) {
13+
next.add(val | num);
14+
}
15+
16+
result.addAll(next);
17+
current = next;
18+
}
19+
20+
return result.size();
21+
}
22+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/**
2+
* @param {number[]} arr
3+
* @return {number}
4+
*/
5+
var subarrayBitwiseORs = function(arr) {
6+
const result = new Set();
7+
let current = new Set();
8+
9+
for (const num of arr) {
10+
const next = new Set();
11+
next.add(num);
12+
13+
for (const val of current) {
14+
next.add(val | num);
15+
}
16+
17+
for (const val of next) {
18+
result.add(val);
19+
}
20+
21+
current = next;
22+
}
23+
24+
return result.size();
25+
};

0 commit comments

Comments
 (0)