898 Bitwise ORs of Subarrays 子數組按位或操作
Description:
We have an array arr of non-negative integers.
For every (contiguous) subarray sub = [arr[i], arr[i + 1], ..., arr[j]] (with i <= j), we take the bitwise OR of all the elements in sub, obtaining a result arr[i] | arr[i + 1] | ... | arr[j].
Return the number of possible results. Results that occur more than once are only counted once in the final answer
Example:
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 <= nums.length <= 5 * 10^4
0 <= nums[i] <= 10^9
題目描述:
我們有一個非負整數數組 A。
對於每個(連續的)子數組 B = [A[i], A[i+1], ..., A[j]] ( i <= j),我們對 B 中的每個元素進行按位或操作,獲得結果 A[i] | A[i+1] | ... | A[j]。
返回可能結果的數量。 (多次出現的結果在最終答案中僅計算一次。)
示例 :
示例 1:
輸入:[0]
輸出:1
解釋:
只有一個可能的結果 0 。
示例 2:
輸入:[1,1,2]
輸出:3
解釋:
可能的子數組爲 [1],[1],[2],[1, 1],[1, 2],[1, 1, 2]。
產生的結果爲 1,1,2,1,3,3 。
有三個唯一值,所以答案是 3 。
示例 3:
輸入:[1,2,4]
輸出:6
解釋:
可能的結果是 1,2,3,4,6,以及 7 。
提示:
1 <= A.length <= 50000
0 <= A[i] <= 10^9
思路:
哈希表 ➕ 剪枝
將所有子數組的或的結果加入哈希表
最後返回哈希表的長度即可
剪枝的策略有兩種
第一種是找到數組的最大值, mask = 2 ^ max_value - 1, 當或運算的值達到 mask 的時候說明後面的值不需要再參與運算了
第二種是修改原數組的方式, 從後往前遍歷 arr[i] | arr[j] = arr[j] 說明 arr[j] 之前的數組或運算結果和自身相同可以剪枝
時間複雜度爲 O(nlgm), 空間複雜度爲 O(nlgm), n 爲數組 arr 的長度, m 爲 arr 的最大值
代碼:
C++:
class Solution
{
public:
int subarrayBitwiseORs(vector<int>& arr)
{
unordered_set<int> result;
int mask = 1, max_value = *max_element(arr.begin(), arr.end()), n = arr.size();
while (mask <= max_value) mask <<= 1;
--mask;
for (int i = 0; i < n; i++)
{
int val = arr[i];
result.insert(val);
for (int j = i - 1; j > -1; j--)
{
if (val == mask) break;
val |= arr[j];
result.insert(val);
}
}
return result.size();
}
};
Java:
class Solution {
public int subarrayBitwiseORs(int[] arr) {
Set<Integer> set = new HashSet<>(65536);
for (int i = 0, n = arr.length; i < n; i++) {
set.add(arr[i]);
for (int j = i - 1; j > -1; j--) {
if ((arr[j] | arr[i]) == arr[j]) break;
arr[j] |= arr[i];
set.add(arr[j]);
}
}
return set.size();
}
}
Python:
class Solution:
def subarrayBitwiseORs(self, arr: List[int]) -> int:
mask, max_value, nums, n = 1, max(arr), set(arr), len(arr)
while max_value >= mask:
mask <<= 1
mask -= 1;
for i in range(n):
val = arr[i]
for j in range(i - 1, -1, -1):
if val == mask:
break
val |= arr[j]
nums.add(val)
return len(nums)