diff --git a/solution/1400-1499/1498.Number of Subsequences That Satisfy the Given Sum Condition/README.md b/solution/1400-1499/1498.Number of Subsequences That Satisfy the Given Sum Condition/README.md index e6ace5471b0df..238ee9e8a551f 100644 --- a/solution/1400-1499/1498.Number of Subsequences That Satisfy the Given Sum Condition/README.md +++ b/solution/1400-1499/1498.Number of Subsequences That Satisfy the Given Sum Condition/README.md @@ -74,13 +74,13 @@ tags: -### 方法一:排序 + 枚举贡献 + 二分查找 +### 方法一:排序 + 二分查找 -由于题目中描述的是子序列,并且涉及到最小元素与最大元素的和,因此我们可以先对数组 `nums` 进行排序。 +由于题目中描述的是子序列,并且涉及到最小元素与最大元素的和,因此我们可以先对数组 $\textit{nums}$ 进行排序。 -然后我们枚举最小元素 $nums[i]$,对于每个 $nums[i]$,我们可以在 $nums[i + 1]$ 到 $nums[n - 1]$ 中找到最大元素 $nums[j]$,使得 $nums[i] + nums[j] \leq target$,此时满足条件的子序列数目为 $2^{j - i}$,其中 $2^{j - i}$ 表示从 $nums[i + 1]$ 到 $nums[j]$ 的所有子序列的数目。我们将所有的子序列数目累加即可。 +然后我们枚举最小元素 $\textit{nums}[i]$,对于每个 $\textit{nums}[i]$,我们可以在 $\textit{nums}[i + 1]$ 到 $\textit{nums}[n - 1]$ 中找到最大元素 $\textit{nums}[j]$,使得 $\textit{nums}[i] + \textit{nums}[j] \leq \textit{target}$,此时满足条件的子序列数目为 $2^{j - i}$,其中 $2^{j - i}$ 表示从 $\textit{nums}[i + 1]$ 到 $\textit{nums}[j]$ 的所有子序列的数目。我们将所有的子序列数目累加即可。 -时间复杂度 $O(n \times \log n)$,空间复杂度 $O(n)$。其中 $n$ 为数组 `nums` 的长度。 +时间复杂度 $O(n \times \log n)$,空间复杂度 $O(n)$。其中 $n$ 为数组 $\textit{nums}$ 的长度。 @@ -118,10 +118,7 @@ class Solution { f[i] = (f[i - 1] * 2) % mod; } int ans = 0; - for (int i = 0; i < n; ++i) { - if (nums[i] * 2L > target) { - break; - } + for (int i = 0; i < n && nums[i] * 2 <= target; ++i) { int j = search(nums, target - nums[i], i + 1) - 1; ans = (ans + f[j - i]) % mod; } @@ -158,10 +155,7 @@ public: f[i] = (f[i - 1] * 2) % mod; } int ans = 0; - for (int i = 0; i < n; ++i) { - if (nums[i] * 2L > target) { - break; - } + for (int i = 0; i < n && nums[i] * 2 <= target; ++i) { int j = upper_bound(nums.begin() + i + 1, nums.end(), target - nums[i]) - nums.begin() - 1; ans = (ans + f[j - i]) % mod; } @@ -193,6 +187,77 @@ func numSubseq(nums []int, target int) (ans int) { } ``` +#### TypeScript + +```ts +function numSubseq(nums: number[], target: number): number { + nums.sort((a, b) => a - b); + const mod = 1e9 + 7; + const n = nums.length; + const f: number[] = Array(n + 1).fill(1); + for (let i = 1; i <= n; ++i) { + f[i] = (f[i - 1] * 2) % mod; + } + + let ans = 0; + for (let i = 0; i < n && nums[i] * 2 <= target; ++i) { + const j = search(nums, target - nums[i], i + 1) - 1; + if (j >= i) { + ans = (ans + f[j - i]) % mod; + } + } + return ans; +} + +function search(nums: number[], x: number, left: number): number { + let right = nums.length; + while (left < right) { + const mid = (left + right) >> 1; + if (nums[mid] > x) { + right = mid; + } else { + left = mid + 1; + } + } + return left; +} +``` + +#### Rust + +```rust +impl Solution { + pub fn num_subseq(mut nums: Vec, target: i32) -> i32 { + nums.sort(); + const MOD: i32 = 1_000_000_007; + let n = nums.len(); + let mut f = vec![1; n + 1]; + for i in 1..=n { + f[i] = (f[i - 1] * 2) % MOD; + } + let mut ans = 0; + for i in 0..n { + if nums[i] * 2 > target { + break; + } + let mut l = i + 1; + let mut r = n; + while l < r { + let m = (l + r) / 2; + if nums[m] > target - nums[i] { + r = m; + } else { + l = m + 1; + } + } + let j = l - 1; + ans = (ans + f[j - i]) % MOD; + } + ans + } +} +``` + diff --git a/solution/1400-1499/1498.Number of Subsequences That Satisfy the Given Sum Condition/README_EN.md b/solution/1400-1499/1498.Number of Subsequences That Satisfy the Given Sum Condition/README_EN.md index 82d339744f91b..9e42491529171 100644 --- a/solution/1400-1499/1498.Number of Subsequences That Satisfy the Given Sum Condition/README_EN.md +++ b/solution/1400-1499/1498.Number of Subsequences That Satisfy the Given Sum Condition/README_EN.md @@ -71,7 +71,13 @@ Number of valid subsequences (63 - 2 = 61). -### Solution 1 +### Solution 1: Sorting + Binary Search + +Since the problem is about subsequences and involves the sum of the minimum and maximum elements, we can first sort the array $\textit{nums}$. + +Then we enumerate the minimum element $\textit{nums}[i]$. For each $\textit{nums}[i]$, we can find the maximum element $\textit{nums}[j]$ in $\textit{nums}[i + 1]$ to $\textit{nums}[n - 1]$ such that $\textit{nums}[i] + \textit{nums}[j] \leq \textit{target}$. The number of valid subsequences in this case is $2^{j - i}$, where $2^{j - i}$ represents all possible subsequences from $\textit{nums}[i + 1]$ to $\textit{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 $\textit{nums}$. @@ -109,10 +115,7 @@ class Solution { f[i] = (f[i - 1] * 2) % mod; } int ans = 0; - for (int i = 0; i < n; ++i) { - if (nums[i] * 2L > target) { - break; - } + for (int i = 0; i < n && nums[i] * 2 <= target; ++i) { int j = search(nums, target - nums[i], i + 1) - 1; ans = (ans + f[j - i]) % mod; } @@ -149,10 +152,7 @@ public: f[i] = (f[i - 1] * 2) % mod; } int ans = 0; - for (int i = 0; i < n; ++i) { - if (nums[i] * 2L > target) { - break; - } + for (int i = 0; i < n && nums[i] * 2 <= target; ++i) { int j = upper_bound(nums.begin() + i + 1, nums.end(), target - nums[i]) - nums.begin() - 1; ans = (ans + f[j - i]) % mod; } @@ -184,6 +184,77 @@ func numSubseq(nums []int, target int) (ans int) { } ``` +#### TypeScript + +```ts +function numSubseq(nums: number[], target: number): number { + nums.sort((a, b) => a - b); + const mod = 1e9 + 7; + const n = nums.length; + const f: number[] = Array(n + 1).fill(1); + for (let i = 1; i <= n; ++i) { + f[i] = (f[i - 1] * 2) % mod; + } + + let ans = 0; + for (let i = 0; i < n && nums[i] * 2 <= target; ++i) { + const j = search(nums, target - nums[i], i + 1) - 1; + if (j >= i) { + ans = (ans + f[j - i]) % mod; + } + } + return ans; +} + +function search(nums: number[], x: number, left: number): number { + let right = nums.length; + while (left < right) { + const mid = (left + right) >> 1; + if (nums[mid] > x) { + right = mid; + } else { + left = mid + 1; + } + } + return left; +} +``` + +#### Rust + +```rust +impl Solution { + pub fn num_subseq(mut nums: Vec, target: i32) -> i32 { + nums.sort(); + const MOD: i32 = 1_000_000_007; + let n = nums.len(); + let mut f = vec![1; n + 1]; + for i in 1..=n { + f[i] = (f[i - 1] * 2) % MOD; + } + let mut ans = 0; + for i in 0..n { + if nums[i] * 2 > target { + break; + } + let mut l = i + 1; + let mut r = n; + while l < r { + let m = (l + r) / 2; + if nums[m] > target - nums[i] { + r = m; + } else { + l = m + 1; + } + } + let j = l - 1; + ans = (ans + f[j - i]) % MOD; + } + ans + } +} +``` + diff --git a/solution/1400-1499/1498.Number of Subsequences That Satisfy the Given Sum Condition/Solution.cpp b/solution/1400-1499/1498.Number of Subsequences That Satisfy the Given Sum Condition/Solution.cpp index 4c4d4dc630bac..f599d59527261 100644 --- a/solution/1400-1499/1498.Number of Subsequences That Satisfy the Given Sum Condition/Solution.cpp +++ b/solution/1400-1499/1498.Number of Subsequences That Satisfy the Given Sum Condition/Solution.cpp @@ -10,10 +10,7 @@ class Solution { f[i] = (f[i - 1] * 2) % mod; } int ans = 0; - for (int i = 0; i < n; ++i) { - if (nums[i] * 2L > target) { - break; - } + for (int i = 0; i < n && nums[i] * 2 <= target; ++i) { int j = upper_bound(nums.begin() + i + 1, nums.end(), target - nums[i]) - nums.begin() - 1; ans = (ans + f[j - i]) % mod; } diff --git a/solution/1400-1499/1498.Number of Subsequences That Satisfy the Given Sum Condition/Solution.java b/solution/1400-1499/1498.Number of Subsequences That Satisfy the Given Sum Condition/Solution.java index 73cd951a7968b..d5ceb81f59e9f 100644 --- a/solution/1400-1499/1498.Number of Subsequences That Satisfy the Given Sum Condition/Solution.java +++ b/solution/1400-1499/1498.Number of Subsequences That Satisfy the Given Sum Condition/Solution.java @@ -9,10 +9,7 @@ public int numSubseq(int[] nums, int target) { f[i] = (f[i - 1] * 2) % mod; } int ans = 0; - for (int i = 0; i < n; ++i) { - if (nums[i] * 2L > target) { - break; - } + for (int i = 0; i < n && nums[i] * 2 <= target; ++i) { int j = search(nums, target - nums[i], i + 1) - 1; ans = (ans + f[j - i]) % mod; } diff --git a/solution/1400-1499/1498.Number of Subsequences That Satisfy the Given Sum Condition/Solution.rs b/solution/1400-1499/1498.Number of Subsequences That Satisfy the Given Sum Condition/Solution.rs new file mode 100644 index 0000000000000..7e07c8502443a --- /dev/null +++ b/solution/1400-1499/1498.Number of Subsequences That Satisfy the Given Sum Condition/Solution.rs @@ -0,0 +1,30 @@ +impl Solution { + pub fn num_subseq(mut nums: Vec, target: i32) -> i32 { + nums.sort(); + const MOD: i32 = 1_000_000_007; + let n = nums.len(); + let mut f = vec![1; n + 1]; + for i in 1..=n { + f[i] = (f[i - 1] * 2) % MOD; + } + let mut ans = 0; + for i in 0..n { + if nums[i] * 2 > target { + break; + } + let mut l = i + 1; + let mut r = n; + while l < r { + let m = (l + r) / 2; + if nums[m] > target - nums[i] { + r = m; + } else { + l = m + 1; + } + } + let j = l - 1; + ans = (ans + f[j - i]) % MOD; + } + ans + } +} diff --git a/solution/1400-1499/1498.Number of Subsequences That Satisfy the Given Sum Condition/Solution.ts b/solution/1400-1499/1498.Number of Subsequences That Satisfy the Given Sum Condition/Solution.ts new file mode 100644 index 0000000000000..e05c6d19d421c --- /dev/null +++ b/solution/1400-1499/1498.Number of Subsequences That Satisfy the Given Sum Condition/Solution.ts @@ -0,0 +1,31 @@ +function numSubseq(nums: number[], target: number): number { + nums.sort((a, b) => a - b); + const mod = 1e9 + 7; + const n = nums.length; + const f: number[] = Array(n + 1).fill(1); + for (let i = 1; i <= n; ++i) { + f[i] = (f[i - 1] * 2) % mod; + } + + let ans = 0; + for (let i = 0; i < n && nums[i] * 2 <= target; ++i) { + const j = search(nums, target - nums[i], i + 1) - 1; + if (j >= i) { + ans = (ans + f[j - i]) % mod; + } + } + return ans; +} + +function search(nums: number[], x: number, left: number): number { + let right = nums.length; + while (left < right) { + const mid = (left + right) >> 1; + if (nums[mid] > x) { + right = mid; + } else { + left = mid + 1; + } + } + return left; +}