2044. Count Number of Maximum Bitwise-OR Subsets
Created: 10/28/2021
Given an integer array nums
, find the maximum possible bitwise OR of a subset of nums
and return the number of different non-empty subsets with the maximum bitwise OR.
An array a
is a subset of an array b
if a
can be obtained from b
by deleting some (possibly zero) elements of b
. Two subsets are considered different if the indices of the elements chosen are different.
The bitwise OR of an array a
is equal to a[0]
OR
a[1]
OR
...
OR
a[a.length - 1]
(0-indexed).
Example 1:
Input: nums = [3,1]
Output: 2
Explanation: The maximum possible bitwise OR of a subset is 3. There are 2 subsets with a bitwise OR of 3:
- [3]
- [3,1]
Example 2:
Input: nums = [2,2,2]
Output: 7
Explanation: All non-empty subsets of [2,2,2] have a bitwise OR of 2. There are 23 - 1 = 7 total subsets.
Example 3:
Input: nums = [3,2,1,5]
Output: 6
Explanation: The maximum possible bitwise OR of a subset is 7. There are 6 subsets with a bitwise OR of 7:
- [3,5]
- [3,1,5]
- [3,2,5]
- [3,2,1,5]
- [2,5]
- [2,1,5]
Constraints:
1 <= nums.length <= 16
1 <= nums[i] <= 10^5
Basic Idea:
有两个思路,首先因为一共只有16个数字,所以即使暴力枚举所有的subsets也只需要O(2^16=65536)的时间复杂度,所以暴力解是行得通的。二则是可以使用DP的思路,利用如下递推公式。时间复杂度为O(len(nums) * bitwise or 结果的数字范围),当nums比较多的时候,复杂度会远优于brute force。
int[][] dp = new int[nums.length + 1][1<<17]
dp[0][0] = 1
for i from 0 to nums.length
for j from 0 to 1<<17
if (dp[i][j] > 0){
dp[i + 1][j] += dp[i][j]
dp[i + 1][nums[i] | j] += dp[i][j]
}
}
}
# dp[i][j] 表示到第i个数字为止,能够通过or产生的j的组合个数
Java Code:
// DP
class Solution {
public int countMaxOrSubsets(int[] nums) {
int N = 1<<17;
int[] dp = new int[N];
dp[0] = 1;
for (int num : nums) {
int[] dp2 = new int[N];
for (int i = 0; i < dp.length; ++i) {
if (dp[i] > 0) {
dp2[i | num] += dp[i];
dp2[i] += dp[i];
}
}
dp = dp2;
}
int max = 0;
int count = 0;
for (int i = 0; i < N; ++i) {
if (dp[i] > 0) {
count = dp[i];
}
}
return count;
}
}
// Brute force
class Solution {
public int countMaxOrSubsets(int[] nums) {
List<List<Integer>> res = new ArrayList<>();
dfs(nums, 0, new ArrayList<>(), res);
TreeMap<Integer, Integer> map = new TreeMap<>();
for (List<Integer> list : res) {
int curr = 0;
for (int num : list) {
curr |= num;
}
map.put(curr, map.getOrDefault(curr, 0) + 1);
}
return map.lastEntry().getValue();
}
private void dfs(int[] nums, int pos, List<Integer> path, List<List<Integer>> res) {
res.add(new ArrayList<>(path));
if (pos == nums.length) {
return;
}
for (int i = pos; i < nums.length; ++i) {
path.add(nums[i]);
dfs(nums, i + 1, path, res);
path.remove(path.size() - 1);
}
}
}
Last updated