You are given an array of integers nums and an integer target.
Return the number of non-empty subsequences of nums such that the sum of the minimum and maximum element on it is less or equal to target. Since the answer may be too large, return it modulo 109 + 7.
Example 1:
Input: nums = [3,5,6,7], target = 9 Output: 4 Explanation: There are 4 subsequences that satisfy the condition. [3] -> Min value + max value <= target (3 + 3 <= 9) [3,5] -> (3 + 5 <= 9) [3,5,6] -> (3 + 6 <= 9) [3,6] -> (3 + 6 <= 9)
Example 2:
Input: nums = [3,3,6,8], target = 10 Output: 6 Explanation: There are 6 subsequences that satisfy the condition. (nums can have repeated numbers). [3] , [3] , [3,3], [3,6] , [3,6] , [3,3,6]
Example 3:
Input: nums = [2,3,3,4,6,7], target = 12 Output: 61 Explanation: There are 63 non-empty subsequences, two of them do not satisfy the condition ([6,7], [7]). Number of valid subsequences (63 - 2 = 61).
Constraints:
1 <= nums.length <= 1051 <= nums[i] <= 1061 <= target <= 106Problem Overview: Given an integer array nums and a target, count the number of non‑empty subsequences where the sum of the minimum and maximum element in that subsequence is less than or equal to the target. The result can be large, so it is returned modulo 1e9 + 7.
Approach 1: Two Pointers with Sorting (Time: O(n log n), Space: O(1) extra)
Sort the array first so the smallest and largest elements of a subsequence are easy to reason about. Use two pointers: left at the start and right at the end. If nums[left] + nums[right] ≤ target, every subset formed by choosing elements between them while fixing nums[left] as the minimum is valid. That contributes 2^(right-left) subsequences. Move left forward to explore the next minimum. If the sum exceeds the target, decrease right to reduce the maximum element. Precompute powers of two to count combinations efficiently.
This approach works because sorting guarantees the smallest element of any chosen subsequence is fixed at left while all elements between left and right are ≤ nums[right]. The scan runs in linear time after sorting. The technique heavily relies on sorting and a classic two pointers sweep.
Approach 2: Dynamic Programming with Binary Indexing (Time: O(n log n), Space: O(n))
Another way is to process numbers in sorted order and maintain counts of valid subsequence boundaries using a Binary Indexed Tree (Fenwick Tree). After sorting, treat each element as a potential maximum. Use binary search to find the largest index where nums[i] + nums[j] ≤ target. A Fenwick Tree stores counts of previously considered elements and helps accumulate how many subsequences can extend with the current value. The DP state essentially counts combinations where the current value acts as the maximum while previously processed values act as potential minimums.
This method is useful when extending the problem to variations that require dynamic frequency updates or range queries. It blends ideas from array processing and indexed prefix sums.
Recommended for interviews: The sorted two‑pointer solution is the expected answer. It reduces the problem to a single linear scan after sorting and uses a simple combinatorial observation with 2^(k). A brute force enumeration of subsequences shows understanding but runs in exponential time. Demonstrating the two‑pointer counting trick signals strong problem‑solving and optimization skills.
This approach involves sorting the array and then using a two pointers method to determine valid subsequences. We focus on the potential minimum and maximum values in a subsequence.
After sorting, use two pointers, one starting from the beginning of the array (for the minimum) and the other from the end (for the maximum). For each minimum, the number of valid subsequences is determined by how many elements from the minimum can pair with elements from the maximum such that their sum is less than or equal to the target. The number of subsequences can be calculated using the binary exponentiation of 2 with the distance between the two pointers.
This C implementation begins by sorting the nums array using qsort. We define a helper function power to calculate powers of 2 modulo a large number efficiently using binary exponentiation. The main function numSubseq then initializes two pointers left and right. For each iteration, if the sum of nums[left] and nums[right] is less than or equal to target, it adds the number of subsequences possible between these two indices to the result. The result is returned modulo 10^9 + 7.
Time Complexity: O(n log n), due to sorting the array.
Space Complexity: O(1), or O(n) if considering the space used by sorting.
This approach involves dynamic programming where pre-computed powers of 2 are used to calculate valid subsequences. Using arrays to store results dynamically avoids repetitive calculations and exploits binary indexing for faster computation on potential subsets.
The idea is to create a precompute power array of size n to store power values of 2 up to n. Iterating with this precompute allows identifying valid subsequences without recalculating powers each iteration, enhancing efficiency especially for extremely large arrays.
The C version creates a precompute array, power_2, storing powers of 2 to speed up the process. In doing so, the calculation of power values in the main loop becomes redundant, cutting down unnecessary iterations, while achieving the same correction via binary checks.
Time Complexity: O(n log n) for sorting. The DP preparation step is O(n).
Space Complexity: O(n) due to the power array creation.
Since the problem is about subsequences and involves the sum of the minimum and maximum elements, we can first sort the array nums.
Then we enumerate the minimum element nums[i]. For each nums[i], we can find the maximum element nums[j] in nums[i + 1] to nums[n - 1] such that nums[i] + nums[j] leq target. The number of valid subsequences in this case is 2^{j - i}, where 2^{j - i} represents all possible subsequences from nums[i + 1] to nums[j]. We sum up the counts of all such subsequences.
The time complexity is O(n times log n), and the space complexity is O(n), where n is the length of the array nums.
| Approach | Complexity |
|---|---|
| Two Pointers with Sorting | Time Complexity: O(n log n), due to sorting the array. |
| Dynamic Programming with Binary Indexing | Time Complexity: O(n log n) for sorting. The DP preparation step is O(n). |
| Sorting + Binary Search | — |
| Approach | Time | Space | When to Use |
|---|---|---|---|
| Two Pointers with Sorting | O(n log n) | O(1) extra | Best practical solution. Works when the array can be sorted and subsequence count depends on min and max. |
| Dynamic Programming with Binary Indexed Tree | O(n log n) | O(n) | Useful for variations needing prefix queries, dynamic counting, or range updates. |
Leetcode 1498 - Number of Subsequences That Satisfy the Given Sum Condition - Python • NeetCode • 38,683 views views
Watch 9 more video solutions →Practice Number of Subsequences That Satisfy the Given Sum Condition with our built-in code editor and test cases.
Practice on FleetCode