Skip to content

Commit 1060b58

Browse files
authored
feat: add solutions to lc problem: No.2389 (#4027)
No.2389.Longest Subsequence With Limited Sum
1 parent c29963f commit 1060b58

File tree

8 files changed

+126
-196
lines changed

8 files changed

+126
-196
lines changed

solution/2300-2399/2389.Longest Subsequence With Limited Sum/README.md

+45-67
Original file line numberDiff line numberDiff line change
@@ -67,11 +67,11 @@ tags:
6767

6868
### 方法一:排序 + 前缀和 + 二分查找
6969

70-
根据题目描述,对于每个 $queries[i]$,我们需要找到一个子序列,使得该子序列的元素和不超过 $queries[i]$,且该子序列的长度最大化。显然,我们应该选择尽可能小的元素,这样才能使得子序列的长度最大化。
70+
根据题目描述,对于每个 $\textit{queries[i]}$,我们需要找到一个子序列,使得该子序列的元素和不超过 $\textit{queries[i]}$,且该子序列的长度最大化。显然,我们应该选择尽可能小的元素,这样才能使得子序列的长度最大化。
7171

72-
因此,我们可以先将数组 $nums$ 进行升序排序,然后对于每个 $queries[i]$,我们可以使用二分查找,找到最小的下标 $j$,使得 $nums[0] + nums[1] + \cdots + nums[j] \gt queries[i]$。此时 $nums[0] + nums[1] + \cdots + nums[j - 1]$ 就是满足条件的子序列的元素和,且该子序列的长度为 $j$。因此,我们可以将 $j$ 加入答案数组中。
72+
因此,我们可以先将数组 $\textit{nums}$ 进行升序排序,然后对于每个 $\textit{queries[i]}$,我们可以使用二分查找,找到最小的下标 $j$,使得 $\textit{nums}[0] + \textit{nums}[1] + \cdots + \textit{nums}[j] > \textit{queries[i]}$。此时 $\textit{nums}[0] + \textit{nums}[1] + \cdots + \textit{nums}[j - 1]$ 就是满足条件的子序列的元素和,且该子序列的长度为 $j$。因此,我们可以将 $j$ 加入答案数组中。
7373

74-
时间复杂度 $O((n + m) \times \log n)$,空间复杂度 $O(n)$ 或 $O(\log n)$。其中 $n$ 和 $m$ 分别是数组 $nums$ 和 $queries$ 的长度。
74+
时间复杂度 $O((n + m) \times \log n)$,空间复杂度 $O(n)$ 或 $O(\log n)$。其中 $n$ 和 $m$ 分别是数组 $\textit{nums}$ 和 $\textit{queries}$ 的长度。
7575

7676
<!-- tabs:start -->
7777

@@ -97,23 +97,11 @@ class Solution {
9797
int m = queries.length;
9898
int[] ans = new int[m];
9999
for (int i = 0; i < m; ++i) {
100-
ans[i] = search(nums, queries[i]);
100+
int j = Arrays.binarySearch(nums, queries[i] + 1);
101+
ans[i] = j < 0 ? -j - 1 : j;
101102
}
102103
return ans;
103104
}
104-
105-
private int search(int[] nums, int x) {
106-
int l = 0, r = nums.length;
107-
while (l < r) {
108-
int mid = (l + r) >> 1;
109-
if (nums[mid] > x) {
110-
r = mid;
111-
} else {
112-
l = mid + 1;
113-
}
114-
}
115-
return l;
116-
}
117105
}
118106
```
119107

@@ -123,13 +111,13 @@ class Solution {
123111
class Solution {
124112
public:
125113
vector<int> answerQueries(vector<int>& nums, vector<int>& queries) {
126-
sort(nums.begin(), nums.end());
114+
ranges::sort(nums);
127115
for (int i = 1; i < nums.size(); i++) {
128116
nums[i] += nums[i - 1];
129117
}
130118
vector<int> ans;
131-
for (auto& q : queries) {
132-
ans.push_back(upper_bound(nums.begin(), nums.end(), q) - nums.begin());
119+
for (const auto& q : queries) {
120+
ans.emplace_back(upper_bound(nums.begin(), nums.end(), q) - nums.begin());
133121
}
134122
return ans;
135123
}
@@ -159,24 +147,7 @@ function answerQueries(nums: number[], queries: number[]): number[] {
159147
for (let i = 1; i < nums.length; i++) {
160148
nums[i] += nums[i - 1];
161149
}
162-
const ans: number[] = [];
163-
const search = (nums: number[], x: number) => {
164-
let l = 0;
165-
let r = nums.length;
166-
while (l < r) {
167-
const mid = (l + r) >> 1;
168-
if (nums[mid] > x) {
169-
r = mid;
170-
} else {
171-
l = mid + 1;
172-
}
173-
}
174-
return l;
175-
};
176-
for (const q of queries) {
177-
ans.push(search(nums, q));
178-
}
179-
return ans;
150+
return queries.map(q => _.sortedIndex(nums, q + 1));
180151
}
181152
```
182153

@@ -185,48 +156,55 @@ function answerQueries(nums: number[], queries: number[]): number[] {
185156
```rust
186157
impl Solution {
187158
pub fn answer_queries(mut nums: Vec<i32>, queries: Vec<i32>) -> Vec<i32> {
188-
let n = nums.len();
189159
nums.sort();
190-
queries
191-
.into_iter()
192-
.map(|query| {
193-
let mut sum = 0;
194-
for i in 0..n {
195-
sum += nums[i];
196-
if sum > query {
197-
return i as i32;
198-
}
199-
}
200-
n as i32
201-
})
202-
.collect()
160+
161+
for i in 1..nums.len() {
162+
nums[i] += nums[i - 1];
163+
}
164+
165+
queries.iter().map(|&q| {
166+
match nums.binary_search(&q) {
167+
Ok(idx) => idx as i32 + 1,
168+
Err(idx) => idx as i32,
169+
}
170+
}).collect()
203171
}
204172
}
205173
```
206174

175+
#### JavaScript
176+
177+
```js
178+
/**
179+
* @param {number[]} nums
180+
* @param {number[]} queries
181+
* @return {number[]}
182+
*/
183+
var answerQueries = function (nums, queries) {
184+
nums.sort((a, b) => a - b);
185+
for (let i = 1; i < nums.length; i++) {
186+
nums[i] += nums[i - 1];
187+
}
188+
return queries.map(q => _.sortedIndex(nums, q + 1));
189+
};
190+
```
191+
207192
#### C#
208193

209194
```cs
210195
public class Solution {
211196
public int[] AnswerQueries(int[] nums, int[] queries) {
212-
int[] result = new int[queries.Length];
213197
Array.Sort(nums);
214-
for (int i = 0; i < queries.Length; i++) {
215-
result[i] = getSubsequent(nums, queries[i]);
198+
for (int i = 1; i < nums.Length; ++i) {
199+
nums[i] += nums[i - 1];
216200
}
217-
return result;
218-
219-
}
220-
221-
public int getSubsequent(int[] nums,int query) {
222-
int sum = 0;
223-
for (int i = 0; i < nums.Length; i++) {
224-
sum += nums[i];
225-
if (sum > query) {
226-
return i;
227-
}
201+
int m = queries.Length;
202+
int[] ans = new int[m];
203+
for (int i = 0; i < m; ++i) {
204+
int j = Array.BinarySearch(nums, queries[i] + 1);
205+
ans[i] = j < 0 ? -j - 1 : j;
228206
}
229-
return nums.Length;
207+
return ans;
230208
}
231209
}
232210
```

solution/2300-2399/2389.Longest Subsequence With Limited Sum/README_EN.md

+45-67
Original file line numberDiff line numberDiff line change
@@ -65,11 +65,11 @@ tags:
6565

6666
### Solution 1: Sorting + Prefix Sum + Binary Search
6767

68-
According to the problem description, for each $queries[i]$, we need to find a subsequence such that the sum of its elements does not exceed $queries[i]$ and the length of this subsequence is maximized. Obviously, we should choose the smallest possible elements to maximize the length of the subsequence.
68+
According to the problem description, for each $\textit{queries[i]}$, we need to find a subsequence such that the sum of its elements does not exceed $\textit{queries[i]}$ and the length of the subsequence is maximized. Obviously, we should choose the smallest possible elements to maximize the length of the subsequence.
6969

70-
Therefore, we can first sort the array $nums$ in ascending order. Then, for each $queries[i]$, we can use binary search to find the smallest index $j$ such that $nums[0] + nums[1] + \cdots + nums[j] \gt queries[i]$. At this point, $nums[0] + nums[1] + \cdots + nums[j - 1]$ is the sum of the elements of the subsequence that meets the condition, and the length of this subsequence is $j$. Therefore, we can add $j$ to the answer array.
70+
Therefore, we can first sort the array $\textit{nums}$ in ascending order, and then for each $\textit{queries[i]}$, we can use binary search to find the smallest index $j$ such that $\textit{nums}[0] + \textit{nums}[1] + \cdots + \textit{nums}[j] > \textit{queries[i]}$. At this point, $\textit{nums}[0] + \textit{nums}[1] + \cdots + \textit{nums}[j - 1]$ is the sum of the elements of the subsequence that meets the condition, and the length of this subsequence is $j$. Therefore, we can add $j$ to the answer array.
7171

72-
The time complexity is $O((n + m) \times \log n)$, and the space complexity is $O(n)$ or $O(\log n)$. Here, $n$ and $m$ are the lengths of the arrays $nums$ and $queries$, respectively.
72+
The time complexity is $O((n + m) \times \log n)$, and the space complexity is $O(n)$ or $O(\log n)$. Here, $n$ and $m$ are the lengths of the arrays $\textit{nums}$ and $\textit{queries}$, respectively.
7373

7474
<!-- tabs:start -->
7575

@@ -95,23 +95,11 @@ class Solution {
9595
int m = queries.length;
9696
int[] ans = new int[m];
9797
for (int i = 0; i < m; ++i) {
98-
ans[i] = search(nums, queries[i]);
98+
int j = Arrays.binarySearch(nums, queries[i] + 1);
99+
ans[i] = j < 0 ? -j - 1 : j;
99100
}
100101
return ans;
101102
}
102-
103-
private int search(int[] nums, int x) {
104-
int l = 0, r = nums.length;
105-
while (l < r) {
106-
int mid = (l + r) >> 1;
107-
if (nums[mid] > x) {
108-
r = mid;
109-
} else {
110-
l = mid + 1;
111-
}
112-
}
113-
return l;
114-
}
115103
}
116104
```
117105

@@ -121,13 +109,13 @@ class Solution {
121109
class Solution {
122110
public:
123111
vector<int> answerQueries(vector<int>& nums, vector<int>& queries) {
124-
sort(nums.begin(), nums.end());
112+
ranges::sort(nums);
125113
for (int i = 1; i < nums.size(); i++) {
126114
nums[i] += nums[i - 1];
127115
}
128116
vector<int> ans;
129-
for (auto& q : queries) {
130-
ans.push_back(upper_bound(nums.begin(), nums.end(), q) - nums.begin());
117+
for (const auto& q : queries) {
118+
ans.emplace_back(upper_bound(nums.begin(), nums.end(), q) - nums.begin());
131119
}
132120
return ans;
133121
}
@@ -157,24 +145,7 @@ function answerQueries(nums: number[], queries: number[]): number[] {
157145
for (let i = 1; i < nums.length; i++) {
158146
nums[i] += nums[i - 1];
159147
}
160-
const ans: number[] = [];
161-
const search = (nums: number[], x: number) => {
162-
let l = 0;
163-
let r = nums.length;
164-
while (l < r) {
165-
const mid = (l + r) >> 1;
166-
if (nums[mid] > x) {
167-
r = mid;
168-
} else {
169-
l = mid + 1;
170-
}
171-
}
172-
return l;
173-
};
174-
for (const q of queries) {
175-
ans.push(search(nums, q));
176-
}
177-
return ans;
148+
return queries.map(q => _.sortedIndex(nums, q + 1));
178149
}
179150
```
180151

@@ -183,48 +154,55 @@ function answerQueries(nums: number[], queries: number[]): number[] {
183154
```rust
184155
impl Solution {
185156
pub fn answer_queries(mut nums: Vec<i32>, queries: Vec<i32>) -> Vec<i32> {
186-
let n = nums.len();
187157
nums.sort();
188-
queries
189-
.into_iter()
190-
.map(|query| {
191-
let mut sum = 0;
192-
for i in 0..n {
193-
sum += nums[i];
194-
if sum > query {
195-
return i as i32;
196-
}
197-
}
198-
n as i32
199-
})
200-
.collect()
158+
159+
for i in 1..nums.len() {
160+
nums[i] += nums[i - 1];
161+
}
162+
163+
queries.iter().map(|&q| {
164+
match nums.binary_search(&q) {
165+
Ok(idx) => idx as i32 + 1,
166+
Err(idx) => idx as i32,
167+
}
168+
}).collect()
201169
}
202170
}
203171
```
204172

173+
#### JavaScript
174+
175+
```js
176+
/**
177+
* @param {number[]} nums
178+
* @param {number[]} queries
179+
* @return {number[]}
180+
*/
181+
var answerQueries = function (nums, queries) {
182+
nums.sort((a, b) => a - b);
183+
for (let i = 1; i < nums.length; i++) {
184+
nums[i] += nums[i - 1];
185+
}
186+
return queries.map(q => _.sortedIndex(nums, q + 1));
187+
};
188+
```
189+
205190
#### C#
206191

207192
```cs
208193
public class Solution {
209194
public int[] AnswerQueries(int[] nums, int[] queries) {
210-
int[] result = new int[queries.Length];
211195
Array.Sort(nums);
212-
for (int i = 0; i < queries.Length; i++) {
213-
result[i] = getSubsequent(nums, queries[i]);
196+
for (int i = 1; i < nums.Length; ++i) {
197+
nums[i] += nums[i - 1];
214198
}
215-
return result;
216-
217-
}
218-
219-
public int getSubsequent(int[] nums,int query) {
220-
int sum = 0;
221-
for (int i = 0; i < nums.Length; i++) {
222-
sum += nums[i];
223-
if (sum > query) {
224-
return i;
225-
}
199+
int m = queries.Length;
200+
int[] ans = new int[m];
201+
for (int i = 0; i < m; ++i) {
202+
int j = Array.BinarySearch(nums, queries[i] + 1);
203+
ans[i] = j < 0 ? -j - 1 : j;
226204
}
227-
return nums.Length;
205+
return ans;
228206
}
229207
}
230208
```
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
class Solution {
22
public:
33
vector<int> answerQueries(vector<int>& nums, vector<int>& queries) {
4-
sort(nums.begin(), nums.end());
4+
ranges::sort(nums);
55
for (int i = 1; i < nums.size(); i++) {
66
nums[i] += nums[i - 1];
77
}
88
vector<int> ans;
9-
for (auto& q : queries) {
10-
ans.push_back(upper_bound(nums.begin(), nums.end(), q) - nums.begin());
9+
for (const auto& q : queries) {
10+
ans.emplace_back(upper_bound(nums.begin(), nums.end(), q) - nums.begin());
1111
}
1212
return ans;
1313
}
14-
};
14+
};
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,15 @@
11
public class Solution {
22
public int[] AnswerQueries(int[] nums, int[] queries) {
3-
int[] result = new int[queries.Length];
43
Array.Sort(nums);
5-
for (int i = 0; i < queries.Length; i++) {
6-
result[i] = getSubsequent(nums, queries[i]);
4+
for (int i = 1; i < nums.Length; ++i) {
5+
nums[i] += nums[i - 1];
76
}
8-
return result;
9-
10-
}
11-
12-
public int getSubsequent(int[] nums,int query) {
13-
int sum = 0;
14-
for (int i = 0; i < nums.Length; i++) {
15-
sum += nums[i];
16-
if (sum > query) {
17-
return i;
18-
}
7+
int m = queries.Length;
8+
int[] ans = new int[m];
9+
for (int i = 0; i < m; ++i) {
10+
int j = Array.BinarySearch(nums, queries[i] + 1);
11+
ans[i] = j < 0 ? -j - 1 : j;
1912
}
20-
return nums.Length;
13+
return ans;
2114
}
2215
}

0 commit comments

Comments
 (0)