Welcome to Subscribe On Youtube
Formatted question description: https://leetcode.ca/all/1498.html
1498. Number of Subsequences That Satisfy the Given Sum Condition (Medium)
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 than target
.
Since the answer may be too large, return it modulo 10^9 + 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 don't satisfy the condition ([6,7], [7]). Number of valid subsequences (63 - 2 = 61).
Example 4:
Input: nums = [5,2,4,1,7,6,8], target = 16 Output: 127 Explanation: All non-empty subset satisfy the condition (2^7 - 1) = 127
Constraints:
1 <= nums.length <= 10^5
1 <= nums[i] <= 10^6
1 <= target <= 10^6
Related Topics:
Sort, Sliding Window
Solution 1. Two pointers
Consider input nums = [3,5,6,7], target = 9
.
For 3
, we can find the maximum number we can use which is 6
. So we get a subarray [3,5,6]
. Then how many subsequences starting with this 3
we can form using this subarray? It should be 2^(len - 1) = 2^2 = 4
because out of [5, 6]
, we just can choose to pick zero, one or two of them.
Then we consider the next element 5
, and the right bound should only decrease so that we can still sum up to 9
. So we can use two pointers, i
scanning elements from left to right, and j
starting from N - 1
and scanning leftwards to find the maximum right boundary.
// OJ: https://leetcode.com/problems/number-of-subsequences-that-satisfy-the-given-sum-condition/
// Time: O(NlogN)
// Space: O(N)
class Solution {
public:
int numSubseq(vector<int>& A, int target) {
sort(begin(A), end(A));
int N = A.size(), ans = 0, mod = 1e9 + 7;
vector<int> p(N, 1);
for (int i = 1; i < N; ++i) p[i] = p[i - 1] * 2 % mod;
for (int i = 0, j = N - 1; i <= j; ++i) {
while (i <= j && A[i] + A[j] > target) --j;
if (i > j) break;
ans = (ans + p[j - i]) % mod;
}
return ans;
}
};
Or use fast pow.
// OJ: https://leetcode.com/problems/number-of-subsequences-that-satisfy-the-given-sum-condition/
// Time: O(NlogN)
// Space: O(1)
int modpow(int base, int exp, int mod) {
base %= mod;
int ans = 1;
for (; exp > 0; exp >>= 1, base = (long)base * base % mod) {
if (exp & 1) ans = ((long)ans * base) % mod;
}
return ans;
}
class Solution {
public:
int numSubseq(vector<int>& A, int target) {
sort(begin(A), end(A));
int N = A.size(), ans = 0, mod = 1e9 + 7;
for (int i = 0, j = N - 1; i <= j; ++i) {
while (i <= j && A[i] + A[j] > target) --j;
if (i > j) break;
ans = (ans + modpow(2, j - i, mod)) % mod;
}
return ans;
}
};
-
class Solution { public int numSubseq(int[] nums, int target) { final int MODULO = 1000000007; int length = nums.length; Integer[] indices = new Integer[length]; for (int i = 0; i < length; i++) indices[i] = i; Arrays.sort(indices, new Comparator<Integer>() { public int compare(Integer index1, Integer index2) { if (nums[index1] != nums[index2]) return nums[index1] - nums[index2]; else return index1 - index2; } }); int[] power2 = new int[length + 1]; power2[0] = 1; for (int i = 1; i <= length; i++) power2[i] = (power2[i - 1] * 2) % MODULO; int count = 0; int pointer = length - 1; for (int i = 0; i < length; i++) { pointer = Math.max(pointer, i); while (pointer > i && nums[indices[pointer]] + nums[indices[i]] > target) pointer--; if (nums[indices[pointer]] + nums[indices[i]] <= target) { int subLength = pointer - i; count = (count + power2[subLength]) % MODULO; } } return count; } } ############ class Solution { public int numSubseq(int[] nums, int target) { Arrays.sort(nums); final int mod = (int) 1e9 + 7; int n = nums.length; int[] f = new int[n + 1]; f[0] = 1; for (int i = 1; i <= n; ++i) { f[i] = (f[i - 1] * 2) % mod; } int ans = 0; for (int i = 0; i < n; ++i) { if (nums[i] * 2L > target) { break; } int j = search(nums, target - nums[i], i + 1) - 1; ans = (ans + f[j - i]) % mod; } return ans; } private int search(int[] nums, int x, int left) { int right = nums.length; while (left < right) { int mid = (left + right) >> 1; if (nums[mid] > x) { right = mid; } else { left = mid + 1; } } return left; } }
-
// OJ: https://leetcode.com/problems/number-of-subsequences-that-satisfy-the-given-sum-condition/ // Time: O(NlogN) // Space: O(N) class Solution { public: int numSubseq(vector<int>& A, int target) { sort(begin(A), end(A)); int N = A.size(), ans = 0, mod = 1e9 + 7; vector<int> p(N, 1); for (int i = 1; i < N; ++i) p[i] = p[i - 1] * 2 % mod; for (int i = 0, j = N - 1; i <= j; ++i) { while (i <= j && A[i] + A[j] > target) --j; if (i > j) break; ans = (ans + p[j - i]) % mod; } return ans; } };
-
class Solution: def numSubseq(self, nums: List[int], target: int) -> int: mod = 10**9 + 7 nums.sort() n = len(nums) f = [1] + [0] * n for i in range(1, n + 1): f[i] = f[i - 1] * 2 % mod ans = 0 for i, x in enumerate(nums): if x * 2 > target: break j = bisect_right(nums, target - x, i + 1) - 1 ans = (ans + f[j - i]) % mod return ans
-
func numSubseq(nums []int, target int) (ans int) { sort.Ints(nums) n := len(nums) f := make([]int, n+1) f[0] = 1 const mod int = 1e9 + 7 for i := 1; i <= n; i++ { f[i] = f[i-1] * 2 % mod } for i, x := range nums { if x*2 > target { break } j := sort.SearchInts(nums[i+1:], target-x+1) + i ans = (ans + f[j-i]) % mod } return }