Skip to content

Commit 2b1762f

Browse files
committed
feat: add solutions to lc problem: No.1498
No.1498.Number of Subsequences That Satisfy the Given Sum Condition
1 parent 0bf2e51 commit 2b1762f

File tree

6 files changed

+220
-29
lines changed

6 files changed

+220
-29
lines changed

solution/1400-1499/1498.Number of Subsequences That Satisfy the Given Sum Condition/README.md

Lines changed: 77 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -74,13 +74,13 @@ tags:
7474

7575
<!-- solution:start -->
7676

77-
### 方法一:排序 + 枚举贡献 + 二分查找
77+
### 方法一:排序 + 二分查找
7878

79-
由于题目中描述的是子序列,并且涉及到最小元素与最大元素的和,因此我们可以先对数组 `nums` 进行排序。
79+
由于题目中描述的是子序列,并且涉及到最小元素与最大元素的和,因此我们可以先对数组 $\textit{nums}$ 进行排序。
8080

81-
然后我们枚举最小元素 $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]$ 的所有子序列的数目。我们将所有的子序列数目累加即可。
81+
然后我们枚举最小元素 $\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]$ 的所有子序列的数目。我们将所有的子序列数目累加即可。
8282

83-
时间复杂度 $O(n \times \log n)$,空间复杂度 $O(n)$。其中 $n$ 为数组 `nums` 的长度。
83+
时间复杂度 $O(n \times \log n)$,空间复杂度 $O(n)$。其中 $n$ 为数组 $\textit{nums}$ 的长度。
8484

8585
<!-- tabs:start -->
8686

@@ -118,10 +118,7 @@ class Solution {
118118
f[i] = (f[i - 1] * 2) % mod;
119119
}
120120
int ans = 0;
121-
for (int i = 0; i < n; ++i) {
122-
if (nums[i] * 2L > target) {
123-
break;
124-
}
121+
for (int i = 0; i < n && nums[i] * 2 <= target; ++i) {
125122
int j = search(nums, target - nums[i], i + 1) - 1;
126123
ans = (ans + f[j - i]) % mod;
127124
}
@@ -158,10 +155,7 @@ public:
158155
f[i] = (f[i - 1] * 2) % mod;
159156
}
160157
int ans = 0;
161-
for (int i = 0; i < n; ++i) {
162-
if (nums[i] * 2L > target) {
163-
break;
164-
}
158+
for (int i = 0; i < n && nums[i] * 2 <= target; ++i) {
165159
int j = upper_bound(nums.begin() + i + 1, nums.end(), target - nums[i]) - nums.begin() - 1;
166160
ans = (ans + f[j - i]) % mod;
167161
}
@@ -193,6 +187,77 @@ func numSubseq(nums []int, target int) (ans int) {
193187
}
194188
```
195189

190+
#### TypeScript
191+
192+
```ts
193+
function numSubseq(nums: number[], target: number): number {
194+
nums.sort((a, b) => a - b);
195+
const mod = 1e9 + 7;
196+
const n = nums.length;
197+
const f: number[] = Array(n + 1).fill(1);
198+
for (let i = 1; i <= n; ++i) {
199+
f[i] = (f[i - 1] * 2) % mod;
200+
}
201+
202+
let ans = 0;
203+
for (let i = 0; i < n && nums[i] * 2 <= target; ++i) {
204+
const j = search(nums, target - nums[i], i + 1) - 1;
205+
if (j >= i) {
206+
ans = (ans + f[j - i]) % mod;
207+
}
208+
}
209+
return ans;
210+
}
211+
212+
function search(nums: number[], x: number, left: number): number {
213+
let right = nums.length;
214+
while (left < right) {
215+
const mid = (left + right) >> 1;
216+
if (nums[mid] > x) {
217+
right = mid;
218+
} else {
219+
left = mid + 1;
220+
}
221+
}
222+
return left;
223+
}
224+
```
225+
226+
#### Rust
227+
228+
```rust
229+
impl Solution {
230+
pub fn num_subseq(mut nums: Vec<i32>, target: i32) -> i32 {
231+
nums.sort();
232+
const MOD: i32 = 1_000_000_007;
233+
let n = nums.len();
234+
let mut f = vec![1; n + 1];
235+
for i in 1..=n {
236+
f[i] = (f[i - 1] * 2) % MOD;
237+
}
238+
let mut ans = 0;
239+
for i in 0..n {
240+
if nums[i] * 2 > target {
241+
break;
242+
}
243+
let mut l = i + 1;
244+
let mut r = n;
245+
while l < r {
246+
let m = (l + r) / 2;
247+
if nums[m] > target - nums[i] {
248+
r = m;
249+
} else {
250+
l = m + 1;
251+
}
252+
}
253+
let j = l - 1;
254+
ans = (ans + f[j - i]) % MOD;
255+
}
256+
ans
257+
}
258+
}
259+
```
260+
196261
<!-- tabs:end -->
197262

198263
<!-- solution:end -->

solution/1400-1499/1498.Number of Subsequences That Satisfy the Given Sum Condition/README_EN.md

Lines changed: 80 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,13 @@ Number of valid subsequences (63 - 2 = 61).
7171

7272
<!-- solution:start -->
7373

74-
### Solution 1
74+
### Solution 1: Sorting + Binary Search
75+
76+
Since the problem is about subsequences and involves the sum of the minimum and maximum elements, we can first sort the array $\textit{nums}$.
77+
78+
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.
79+
80+
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}$.
7581

7682
<!-- tabs:start -->
7783

@@ -109,10 +115,7 @@ class Solution {
109115
f[i] = (f[i - 1] * 2) % mod;
110116
}
111117
int ans = 0;
112-
for (int i = 0; i < n; ++i) {
113-
if (nums[i] * 2L > target) {
114-
break;
115-
}
118+
for (int i = 0; i < n && nums[i] * 2 <= target; ++i) {
116119
int j = search(nums, target - nums[i], i + 1) - 1;
117120
ans = (ans + f[j - i]) % mod;
118121
}
@@ -149,10 +152,7 @@ public:
149152
f[i] = (f[i - 1] * 2) % mod;
150153
}
151154
int ans = 0;
152-
for (int i = 0; i < n; ++i) {
153-
if (nums[i] * 2L > target) {
154-
break;
155-
}
155+
for (int i = 0; i < n && nums[i] * 2 <= target; ++i) {
156156
int j = upper_bound(nums.begin() + i + 1, nums.end(), target - nums[i]) - nums.begin() - 1;
157157
ans = (ans + f[j - i]) % mod;
158158
}
@@ -184,6 +184,77 @@ func numSubseq(nums []int, target int) (ans int) {
184184
}
185185
```
186186

187+
#### TypeScript
188+
189+
```ts
190+
function numSubseq(nums: number[], target: number): number {
191+
nums.sort((a, b) => a - b);
192+
const mod = 1e9 + 7;
193+
const n = nums.length;
194+
const f: number[] = Array(n + 1).fill(1);
195+
for (let i = 1; i <= n; ++i) {
196+
f[i] = (f[i - 1] * 2) % mod;
197+
}
198+
199+
let ans = 0;
200+
for (let i = 0; i < n && nums[i] * 2 <= target; ++i) {
201+
const j = search(nums, target - nums[i], i + 1) - 1;
202+
if (j >= i) {
203+
ans = (ans + f[j - i]) % mod;
204+
}
205+
}
206+
return ans;
207+
}
208+
209+
function search(nums: number[], x: number, left: number): number {
210+
let right = nums.length;
211+
while (left < right) {
212+
const mid = (left + right) >> 1;
213+
if (nums[mid] > x) {
214+
right = mid;
215+
} else {
216+
left = mid + 1;
217+
}
218+
}
219+
return left;
220+
}
221+
```
222+
223+
#### Rust
224+
225+
```rust
226+
impl Solution {
227+
pub fn num_subseq(mut nums: Vec<i32>, target: i32) -> i32 {
228+
nums.sort();
229+
const MOD: i32 = 1_000_000_007;
230+
let n = nums.len();
231+
let mut f = vec![1; n + 1];
232+
for i in 1..=n {
233+
f[i] = (f[i - 1] * 2) % MOD;
234+
}
235+
let mut ans = 0;
236+
for i in 0..n {
237+
if nums[i] * 2 > target {
238+
break;
239+
}
240+
let mut l = i + 1;
241+
let mut r = n;
242+
while l < r {
243+
let m = (l + r) / 2;
244+
if nums[m] > target - nums[i] {
245+
r = m;
246+
} else {
247+
l = m + 1;
248+
}
249+
}
250+
let j = l - 1;
251+
ans = (ans + f[j - i]) % MOD;
252+
}
253+
ans
254+
}
255+
}
256+
```
257+
187258
<!-- tabs:end -->
188259

189260
<!-- solution:end -->

solution/1400-1499/1498.Number of Subsequences That Satisfy the Given Sum Condition/Solution.cpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,7 @@ class Solution {
1010
f[i] = (f[i - 1] * 2) % mod;
1111
}
1212
int ans = 0;
13-
for (int i = 0; i < n; ++i) {
14-
if (nums[i] * 2L > target) {
15-
break;
16-
}
13+
for (int i = 0; i < n && nums[i] * 2 <= target; ++i) {
1714
int j = upper_bound(nums.begin() + i + 1, nums.end(), target - nums[i]) - nums.begin() - 1;
1815
ans = (ans + f[j - i]) % mod;
1916
}

solution/1400-1499/1498.Number of Subsequences That Satisfy the Given Sum Condition/Solution.java

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,7 @@ public int numSubseq(int[] nums, int target) {
99
f[i] = (f[i - 1] * 2) % mod;
1010
}
1111
int ans = 0;
12-
for (int i = 0; i < n; ++i) {
13-
if (nums[i] * 2L > target) {
14-
break;
15-
}
12+
for (int i = 0; i < n && nums[i] * 2 <= target; ++i) {
1613
int j = search(nums, target - nums[i], i + 1) - 1;
1714
ans = (ans + f[j - i]) % mod;
1815
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
impl Solution {
2+
pub fn num_subseq(mut nums: Vec<i32>, target: i32) -> i32 {
3+
nums.sort();
4+
const MOD: i32 = 1_000_000_007;
5+
let n = nums.len();
6+
let mut f = vec![1; n + 1];
7+
for i in 1..=n {
8+
f[i] = (f[i - 1] * 2) % MOD;
9+
}
10+
let mut ans = 0;
11+
for i in 0..n {
12+
if nums[i] * 2 > target {
13+
break;
14+
}
15+
let mut l = i + 1;
16+
let mut r = n;
17+
while l < r {
18+
let m = (l + r) / 2;
19+
if nums[m] > target - nums[i] {
20+
r = m;
21+
} else {
22+
l = m + 1;
23+
}
24+
}
25+
let j = l - 1;
26+
ans = (ans + f[j - i]) % MOD;
27+
}
28+
ans
29+
}
30+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
function numSubseq(nums: number[], target: number): number {
2+
nums.sort((a, b) => a - b);
3+
const mod = 1e9 + 7;
4+
const n = nums.length;
5+
const f: number[] = Array(n + 1).fill(1);
6+
for (let i = 1; i <= n; ++i) {
7+
f[i] = (f[i - 1] * 2) % mod;
8+
}
9+
10+
let ans = 0;
11+
for (let i = 0; i < n && nums[i] * 2 <= target; ++i) {
12+
const j = search(nums, target - nums[i], i + 1) - 1;
13+
if (j >= i) {
14+
ans = (ans + f[j - i]) % mod;
15+
}
16+
}
17+
return ans;
18+
}
19+
20+
function search(nums: number[], x: number, left: number): number {
21+
let right = nums.length;
22+
while (left < right) {
23+
const mid = (left + right) >> 1;
24+
if (nums[mid] > x) {
25+
right = mid;
26+
} else {
27+
left = mid + 1;
28+
}
29+
}
30+
return left;
31+
}

0 commit comments

Comments
 (0)