Skip to content

Commit ea0a775

Browse files
committed
feat: add solutions to lc problem: No.2389
No.2389.Longest Subsequence With Limited Sum
1 parent c9226e4 commit ea0a775

File tree

7 files changed

+133
-149
lines changed

7 files changed

+133
-149
lines changed

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

Lines changed: 47 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,11 @@
4949

5050
**方法一:排序 + 前缀和 + 二分查找**
5151

52-
`nums` 排序,对于每个 `queries[i]`,求出 `nums` 中所有元素之和小于等于 `queries[i]` 的子序列的最大长度
52+
根据题目描述,对于每个 $queries[i]$,我们需要找到一个子序列,使得该子序列的元素和不超过 $queries[i]$,且该子序列的长度最大化。显然,我们应该选择尽可能小的元素,这样才能使得子序列的长度最大化
5353

54-
时间复杂度 $O((n+m)\times logn)$。其中 $n$ 和 $m$ 分别为 `nums``queries` 的长度。
54+
因此,我们可以先将数组 $nums$ 进行升序排序,然后对于每个 $queries[i]$,我们可以使用二分查找,找到最小的下标 $j$,使得 $nums[0] + nums[1] + \cdots + nums[j] \gt queries[i]$。此时 $nums[0] + nums[1] + \cdots + nums[j - 1]$ 就是满足条件的子序列的元素和,且该子序列的长度为 $j$。因此,我们可以将 $j$ 加入答案数组中。
55+
56+
时间复杂度 $O((n + m) \times \log n)$,空间复杂度 $O(n)$ 或 $O(\log n)$。其中 $n$ 和 $m$ 分别是数组 $nums$ 和 $queries$ 的长度。
5557

5658
<!-- tabs:start -->
5759

@@ -64,7 +66,7 @@ class Solution:
6466
def answerQueries(self, nums: List[int], queries: List[int]) -> List[int]:
6567
nums.sort()
6668
s = list(accumulate(nums))
67-
return [bisect_right(s, v) for v in queries]
69+
return [bisect_right(s, q) for q in queries]
6870
```
6971

7072
### **Java**
@@ -75,30 +77,28 @@ class Solution:
7577
class Solution {
7678
public int[] answerQueries(int[] nums, int[] queries) {
7779
Arrays.sort(nums);
78-
int n = nums.length;
79-
int[] s = new int[n + 1];
80-
for (int i = 0; i < n; ++i) {
81-
s[i + 1] = s[i] + nums[i];
80+
for (int i = 1; i < nums.length; ++i) {
81+
nums[i] += nums[i - 1];
8282
}
8383
int m = queries.length;
8484
int[] ans = new int[m];
8585
for (int i = 0; i < m; ++i) {
86-
ans[i] = search(s, queries[i]);
86+
ans[i] = search(nums, queries[i]);
8787
}
8888
return ans;
8989
}
90-
91-
private int search(int[] s, int v) {
92-
int left = 1, right = s.length;
93-
while (left < right) {
94-
int mid = (left + right) >> 1;
95-
if (s[mid] > v) {
96-
right = mid;
90+
91+
private int search(int[] nums, int x) {
92+
int l = 0, r = nums.length;
93+
while (l < r) {
94+
int mid = (l + r) >> 1;
95+
if (nums[mid] > x) {
96+
r = mid;
9797
} else {
98-
left = mid + 1;
98+
l = mid + 1;
9999
}
100100
}
101-
return left - 1;
101+
return l;
102102
}
103103
}
104104
```
@@ -110,14 +110,12 @@ class Solution {
110110
public:
111111
vector<int> answerQueries(vector<int>& nums, vector<int>& queries) {
112112
sort(nums.begin(), nums.end());
113-
int n = nums.size(), m = queries.size();
114-
vector<int> s(n + 1);
115-
for (int i = 0; i < n; ++i) {
116-
s[i + 1] = s[i] + nums[i];
113+
for (int i = 1; i < nums.size(); i++) {
114+
nums[i] += nums[i - 1];
117115
}
118-
vector<int> ans(m);
119-
for (int i = 0; i < m; ++i) {
120-
ans[i] = upper_bound(s.begin() + 1, s.end(), queries[i]) - s.begin() - 1;
116+
vector<int> ans;
117+
for (auto& q : queries) {
118+
ans.push_back(upper_bound(nums.begin(), nums.end(), q) - nums.begin());
121119
}
122120
return ans;
123121
}
@@ -127,46 +125,44 @@ public:
127125
### **Go**
128126
129127
```go
130-
func answerQueries(nums []int, queries []int) []int {
128+
func answerQueries(nums []int, queries []int) (ans []int) {
131129
sort.Ints(nums)
132-
n, m := len(nums), len(queries)
133-
s := make([]int, n+1)
134-
for i, v := range nums {
135-
s[i+1] = s[i] + v
130+
for i := 1; i < len(nums); i++ {
131+
nums[i] += nums[i-1]
136132
}
137-
ans := make([]int, m)
138-
for i, v := range queries {
139-
left, right := 1, len(s)
140-
for left < right {
141-
mid := (left + right) >> 1
142-
if s[mid] > v {
143-
right = mid
144-
} else {
145-
left = mid + 1
146-
}
147-
}
148-
ans[i] = left - 1
133+
for _, q := range queries {
134+
ans = append(ans, sort.SearchInts(nums, q+1))
149135
}
150-
return ans
136+
return
151137
}
152138
```
153139

154140
### **TypeScript**
155141

156142
```ts
157143
function answerQueries(nums: number[], queries: number[]): number[] {
158-
const n = nums.length;
159144
nums.sort((a, b) => a - b);
160-
return queries.map(query => {
161-
let sum = 0;
162-
for (let i = 0; i < n; i++) {
163-
sum += nums[i];
164-
if (sum > query) {
165-
return i;
145+
for (let i = 1; i < nums.length; i++) {
146+
nums[i] += nums[i - 1];
147+
}
148+
const ans: number[] = [];
149+
const search = (nums: number[], x: number) => {
150+
let l = 0;
151+
let r = nums.length;
152+
while (l < r) {
153+
const mid = (l + r) >> 1;
154+
if (nums[mid] > x) {
155+
r = mid;
156+
} else {
157+
l = mid + 1;
166158
}
167159
}
168-
return n;
169-
});
160+
return l;
161+
};
162+
for (const q of queries) {
163+
ans.push(search(nums, q));
164+
}
165+
return ans;
170166
}
171167
```
172168

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

Lines changed: 43 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ class Solution:
5050
def answerQueries(self, nums: List[int], queries: List[int]) -> List[int]:
5151
nums.sort()
5252
s = list(accumulate(nums))
53-
return [bisect_right(s, v) for v in queries]
53+
return [bisect_right(s, q) for q in queries]
5454
```
5555

5656
### **Java**
@@ -59,30 +59,28 @@ class Solution:
5959
class Solution {
6060
public int[] answerQueries(int[] nums, int[] queries) {
6161
Arrays.sort(nums);
62-
int n = nums.length;
63-
int[] s = new int[n + 1];
64-
for (int i = 0; i < n; ++i) {
65-
s[i + 1] = s[i] + nums[i];
62+
for (int i = 1; i < nums.length; ++i) {
63+
nums[i] += nums[i - 1];
6664
}
6765
int m = queries.length;
6866
int[] ans = new int[m];
6967
for (int i = 0; i < m; ++i) {
70-
ans[i] = search(s, queries[i]);
68+
ans[i] = search(nums, queries[i]);
7169
}
7270
return ans;
7371
}
74-
75-
private int search(int[] s, int v) {
76-
int left = 1, right = s.length;
77-
while (left < right) {
78-
int mid = (left + right) >> 1;
79-
if (s[mid] > v) {
80-
right = mid;
72+
73+
private int search(int[] nums, int x) {
74+
int l = 0, r = nums.length;
75+
while (l < r) {
76+
int mid = (l + r) >> 1;
77+
if (nums[mid] > x) {
78+
r = mid;
8179
} else {
82-
left = mid + 1;
80+
l = mid + 1;
8381
}
8482
}
85-
return left - 1;
83+
return l;
8684
}
8785
}
8886
```
@@ -94,14 +92,12 @@ class Solution {
9492
public:
9593
vector<int> answerQueries(vector<int>& nums, vector<int>& queries) {
9694
sort(nums.begin(), nums.end());
97-
int n = nums.size(), m = queries.size();
98-
vector<int> s(n + 1);
99-
for (int i = 0; i < n; ++i) {
100-
s[i + 1] = s[i] + nums[i];
95+
for (int i = 1; i < nums.size(); i++) {
96+
nums[i] += nums[i - 1];
10197
}
102-
vector<int> ans(m);
103-
for (int i = 0; i < m; ++i) {
104-
ans[i] = upper_bound(s.begin() + 1, s.end(), queries[i]) - s.begin() - 1;
98+
vector<int> ans;
99+
for (auto& q : queries) {
100+
ans.push_back(upper_bound(nums.begin(), nums.end(), q) - nums.begin());
105101
}
106102
return ans;
107103
}
@@ -111,46 +107,44 @@ public:
111107
### **Go**
112108
113109
```go
114-
func answerQueries(nums []int, queries []int) []int {
110+
func answerQueries(nums []int, queries []int) (ans []int) {
115111
sort.Ints(nums)
116-
n, m := len(nums), len(queries)
117-
s := make([]int, n+1)
118-
for i, v := range nums {
119-
s[i+1] = s[i] + v
112+
for i := 1; i < len(nums); i++ {
113+
nums[i] += nums[i-1]
120114
}
121-
ans := make([]int, m)
122-
for i, v := range queries {
123-
left, right := 1, len(s)
124-
for left < right {
125-
mid := (left + right) >> 1
126-
if s[mid] > v {
127-
right = mid
128-
} else {
129-
left = mid + 1
130-
}
131-
}
132-
ans[i] = left - 1
115+
for _, q := range queries {
116+
ans = append(ans, sort.SearchInts(nums, q+1))
133117
}
134-
return ans
118+
return
135119
}
136120
```
137121

138122
### **TypeScript**
139123

140124
```ts
141125
function answerQueries(nums: number[], queries: number[]): number[] {
142-
const n = nums.length;
143126
nums.sort((a, b) => a - b);
144-
return queries.map(query => {
145-
let sum = 0;
146-
for (let i = 0; i < n; i++) {
147-
sum += nums[i];
148-
if (sum > query) {
149-
return i;
127+
for (let i = 1; i < nums.length; i++) {
128+
nums[i] += nums[i - 1];
129+
}
130+
const ans: number[] = [];
131+
const search = (nums: number[], x: number) => {
132+
let l = 0;
133+
let r = nums.length;
134+
while (l < r) {
135+
const mid = (l + r) >> 1;
136+
if (nums[mid] > x) {
137+
r = mid;
138+
} else {
139+
l = mid + 1;
150140
}
151141
}
152-
return n;
153-
});
142+
return l;
143+
};
144+
for (const q of queries) {
145+
ans.push(search(nums, q));
146+
}
147+
return ans;
154148
}
155149
```
156150

solution/2300-2399/2389.Longest Subsequence With Limited Sum/Solution.cpp

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,12 @@ class Solution {
22
public:
33
vector<int> answerQueries(vector<int>& nums, vector<int>& queries) {
44
sort(nums.begin(), nums.end());
5-
int n = nums.size(), m = queries.size();
6-
vector<int> s(n + 1);
7-
for (int i = 0; i < n; ++i) {
8-
s[i + 1] = s[i] + nums[i];
5+
for (int i = 1; i < nums.size(); i++) {
6+
nums[i] += nums[i - 1];
97
}
10-
vector<int> ans(m);
11-
for (int i = 0; i < m; ++i) {
12-
ans[i] = upper_bound(s.begin() + 1, s.end(), queries[i]) - s.begin() - 1;
8+
vector<int> ans;
9+
for (auto& q : queries) {
10+
ans.push_back(upper_bound(nums.begin(), nums.end(), q) - nums.begin());
1311
}
1412
return ans;
1513
}
Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,10 @@
1-
func answerQueries(nums []int, queries []int) []int {
1+
func answerQueries(nums []int, queries []int) (ans []int) {
22
sort.Ints(nums)
3-
n, m := len(nums), len(queries)
4-
s := make([]int, n+1)
5-
for i, v := range nums {
6-
s[i+1] = s[i] + v
3+
for i := 1; i < len(nums); i++ {
4+
nums[i] += nums[i-1]
75
}
8-
ans := make([]int, m)
9-
for i, v := range queries {
10-
left, right := 1, len(s)
11-
for left < right {
12-
mid := (left + right) >> 1
13-
if s[mid] > v {
14-
right = mid
15-
} else {
16-
left = mid + 1
17-
}
18-
}
19-
ans[i] = left - 1
6+
for _, q := range queries {
7+
ans = append(ans, sort.SearchInts(nums, q+1))
208
}
21-
return ans
9+
return
2210
}
Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,27 @@
11
class Solution {
22
public int[] answerQueries(int[] nums, int[] queries) {
33
Arrays.sort(nums);
4-
int n = nums.length;
5-
int[] s = new int[n + 1];
6-
for (int i = 0; i < n; ++i) {
7-
s[i + 1] = s[i] + nums[i];
4+
for (int i = 1; i < nums.length; ++i) {
5+
nums[i] += nums[i - 1];
86
}
97
int m = queries.length;
108
int[] ans = new int[m];
119
for (int i = 0; i < m; ++i) {
12-
ans[i] = search(s, queries[i]);
10+
ans[i] = search(nums, queries[i]);
1311
}
1412
return ans;
1513
}
16-
17-
private int search(int[] s, int v) {
18-
int left = 1, right = s.length;
19-
while (left < right) {
20-
int mid = (left + right) >> 1;
21-
if (s[mid] > v) {
22-
right = mid;
14+
15+
private int search(int[] nums, int x) {
16+
int l = 0, r = nums.length;
17+
while (l < r) {
18+
int mid = (l + r) >> 1;
19+
if (nums[mid] > x) {
20+
r = mid;
2321
} else {
24-
left = mid + 1;
22+
l = mid + 1;
2523
}
2624
}
27-
return left - 1;
25+
return l;
2826
}
2927
}

0 commit comments

Comments
 (0)