Watch 3 video solutions for Number of Effective Subsequences, a hard level problem involving Array, Math, Dynamic Programming. This walkthrough by CodeWithMeGuys has 467 views views. Want to try solving it yourself? Practice on FleetCode or read the detailed text solution.
You are given an integer array nums.
The strength of the array is defined as the bitwise OR of all its elements.
A subsequence is considered effective if removing that subsequence strictly decreases the strength of the remaining elements.
Return the number of effective subsequences in nums. Since the answer may be large, return it modulo 109 + 7.
The bitwise OR of an empty array is 0.
Example 1:
Input: nums = [1,2,3]
Output: 3
Explanation:
1 OR 2 OR 3 = 3.[1, 3]: The remaining element [2] has a Bitwise OR of 2.[2, 3]: The remaining element [1] has a Bitwise OR of 1.[1, 2, 3]: The remaining elements [] have a Bitwise OR of 0.Example 2:
Input: nums = [7,4,6]
Output: 4
Explanation:
7 OR 4 OR 6 = 7.[7]: The remaining elements [4, 6] have a Bitwise OR of 6.[7, 4]: The remaining element [6] has a Bitwise OR of 6.[7, 6]: The remaining element [4] has a Bitwise OR of 4.[7, 4, 6]: The remaining elements [] have a Bitwise OR of 0.Example 3:
Input: nums = [8,8]
Output: 1
Explanation:
8 OR 8 = 8.[8, 8] is effective since removing it leaves [] which has a Bitwise OR of 0.Example 4:
Input: nums = [2,2,1]
Output: 5
Explanation:
2 OR 2 OR 1 = 3.[1]: The remaining elements [2, 2] have a Bitwise OR of 2.[2, 1] (using nums[0], nums[2]): The remaining element [2] has a Bitwise OR of 2.[2, 1] (using nums[1], nums[2]): The remaining element [2] has a Bitwise OR of 2.[2, 2]: The remaining element [1] has a Bitwise OR of 1.[2, 2, 1]: The remaining elements [] have a Bitwise OR of 0.
Constraints:
1 <= nums.length <= 1051 <= nums[i] <= 106Problem Overview: You receive an integer array and must count how many subsequences satisfy the definition of an effective subsequence. The key challenge is that subsequences grow exponentially, so enumerating all possibilities quickly becomes infeasible. The goal is to aggregate subsequence properties using bit operations and dynamic programming rather than generating them explicitly.
Approach 1: Brute Force Subsequence Enumeration (O(2^n * B) time, O(1) space)
The most direct method generates every subsequence using bitmask enumeration. For each mask from 0 to (1<<n)-1, compute the combined bitwise property of the chosen elements and check whether it satisfies the "effective" condition. This verifies correctness but scales poorly because the number of subsequences doubles with each element. Even with small arrays, 2^n combinations become impractical.
Approach 2: Dynamic Programming on Bitmasks (O(n * M) time, O(M) space)
A better strategy tracks subsequence states using a DP table indexed by bitmasks. Each state dp[mask] represents how many subsequences produce that mask as their combined bitwise result. While iterating through the array, update states by combining the current number with existing masks using bitwise operations such as & or | depending on the problem definition. This avoids explicit subsequence generation and instead aggregates counts. The number of masks M depends on the bit width of the numbers, typically bounded by 2^B where B is the number of relevant bits.
Approach 3: Bit Frequency + Combinatorics Optimization (O(n * B) time, O(B) space)
The optimal solution leverages the observation that subsequence validity depends only on specific bit patterns. Instead of storing every mask, track how many numbers contribute to each bit position. Combinatorics then determines how many subsequences preserve the required bit structure. Precompute powers of two to represent inclusion or exclusion of elements and accumulate valid counts per bit configuration. This approach reduces state space dramatically and relies heavily on bit manipulation and combinatorics rather than full mask enumeration.
The transitions resemble typical dynamic programming patterns: process each element once, update aggregated counts, and avoid recomputing overlapping subsequence states.
Recommended for interviews: Start by explaining the brute force enumeration to show you understand the subsequence search space. Then transition to the bitmask DP idea that aggregates states instead of generating them. The optimized combinatorics-based counting is usually what interviewers expect for a Hard problem because it reduces exponential growth to near-linear complexity with respect to the array size.
| Approach | Time | Space | When to Use |
|---|---|---|---|
| Brute Force Subsequence Enumeration | O(2^n * B) | O(1) | Small arrays or for validating correctness during reasoning |
| Dynamic Programming on Bitmasks | O(n * M) | O(M) | General solution when bit range is manageable |
| Bit Frequency + Combinatorics | O(n * B) | O(B) | Optimal approach when subsequence validity depends on bit structure |