Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 9b9643e

Browse files
feat: add solutions to lc problem: No.2926 (doocs#1942)
No.2926.Maximum Balanced Subsequence Sum
1 parent f662e8a commit 9b9643e

File tree

8 files changed

+816
-9
lines changed

8 files changed

+816
-9
lines changed

‎solution/2600-2699/2609.Find the Longest Balanced Substring of a Binary String/README.md‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@
6666
遍历字符串 $s,ドル对于当前字符 $c$:
6767

6868
- 如果当前字符为 `'0'`,我们判断此时 $one$ 是否大于 0ドル,ドル是则将 $zero$ 和 $one$ 重置为 0ドル,ドル接下来将 $zero$ 加 1ドル$。
69-
- 如果当前字符为 `'1'`,则将 $one$ 加 1ドル,ドル并更新答案为 $ans = max(ans, 2 \times min(one, zero))$。
69+
- 如果当前字符为 `'1'`,则将 $one$ 加 1ドル,ドル并更新答案为 $ans = \max(ans, 2 \times \min(one, zero))$。
7070

7171
遍历结束后,即可得到最长的平衡子串的长度。
7272

@@ -326,7 +326,7 @@ impl Solution {
326326
if s.as_bytes()[k] == b'1' {
327327
cnt += 1;
328328
} else if cnt > 0 {
329-
return false
329+
return false;
330330
}
331331
}
332332

@@ -369,7 +369,7 @@ impl Solution {
369369
zero += 1;
370370
} else {
371371
one += 1;
372-
ans = std::cmp::max(ans, std::cmp::min(zero, one) * 2)
372+
ans = std::cmp::max(ans, std::cmp::min(zero, one) * 2);
373373
}
374374
}
375375

‎solution/2900-2999/2926.Maximum Balanced Subsequence Sum/README.md‎

Lines changed: 279 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,34 +67,310 @@ nums[3] - nums[0] >= 3 - 0 。
6767

6868
<!-- 这里可写通用的实现逻辑 -->
6969

70+
**方法一:动态规划 + 树状数组**
71+
72+
根据题目描述,我们可以将不等式 $nums[i] - nums[j] \ge i - j$ 转化为 $nums[i] - i \ge nums[j] - j,ドル因此,我们考虑定义一个新数组 $arr,ドル其中 $arr[i] = nums[i] - i,ドル那么平衡子序列满足对于任意 $j \lt i,ドル都有 $arr[j] \le arr[i]$。即题目转换为求在 $arr$ 中选出一个递增子序列,使得对应的 $nums$ 的和最大。
73+
74+
假设 $i$ 是子序列中最后一个元素的下标,那么我们考虑子序列倒数第二个元素的下标 $j,ドル如果 $arr[j] \le arr[i],ドル我们可以考虑是否要将 $j$ 加入到子序列中。
75+
76+
因此,我们定义 $f[i]$ 表示子序列最后一个元素的下标为 $i$ 时,对应的 $nums$ 的最大和,那么答案为 $\max_{i=0}^{n-1} f[i]$。
77+
78+
状态转移方程为:
79+
80+
$$
81+
f[i] = \max(\max_{j=0}^{i-1} f[j], 0) + nums[i]
82+
$$
83+
84+
其中 $j$ 满足 $arr[j] \le arr[i]$。
85+
86+
我们可以使用树状数组来维护前缀的最大值,即对于每个 $arr[i],ドル我们维护前缀 $arr[0..i]$ 中 $f[i]$ 的最大值。
87+
88+
时间复杂度 $O(n \times \log n),ドル空间复杂度 $O(n)$。其中 $n$ 为数组 $nums$ 的长度。
89+
7090
<!-- tabs:start -->
7191

7292
### **Python3**
7393

7494
<!-- 这里可写当前语言的特殊实现逻辑 -->
7595

7696
```python
77-
97+
class BinaryIndexedTree:
98+
def __init__(self, n: int):
99+
self.n = n
100+
self.c = [-inf] * (n + 1)
101+
102+
def update(self, x: int, v: int):
103+
while x <= self.n:
104+
self.c[x] = max(self.c[x], v)
105+
x += x & -x
106+
107+
def query(self, x: int) -> int:
108+
mx = -inf
109+
while x:
110+
mx = max(mx, self.c[x])
111+
x -= x & -x
112+
return mx
113+
114+
115+
class Solution:
116+
def maxBalancedSubsequenceSum(self, nums: List[int]) -> int:
117+
arr = [x - i for i, x in enumerate(nums)]
118+
s = sorted(set(arr))
119+
tree = BinaryIndexedTree(len(s))
120+
for i, x in enumerate(nums):
121+
j = bisect_left(s, x - i) + 1
122+
v = max(tree.query(j), 0) + x
123+
tree.update(j, v)
124+
return tree.query(len(s))
78125
```
79126

80127
### **Java**
81128

82129
<!-- 这里可写当前语言的特殊实现逻辑 -->
83130

84131
```java
85-
132+
class BinaryIndexedTree {
133+
private int n;
134+
private long[] c;
135+
private final long inf = 1L << 60;
136+
137+
public BinaryIndexedTree(int n) {
138+
this.n = n;
139+
c = new long[n + 1];
140+
Arrays.fill(c, -inf);
141+
}
142+
143+
public void update(int x, long v) {
144+
while (x <= n) {
145+
c[x] = Math.max(c[x], v);
146+
x += x & -x;
147+
}
148+
}
149+
150+
public long query(int x) {
151+
long mx = -inf;
152+
while (x > 0) {
153+
mx = Math.max(mx, c[x]);
154+
x -= x & -x;
155+
}
156+
return mx;
157+
}
158+
}
159+
160+
class Solution {
161+
public long maxBalancedSubsequenceSum(int[] nums) {
162+
int n = nums.length;
163+
int[] arr = new int[n];
164+
for (int i = 0; i < n; ++i) {
165+
arr[i] = nums[i] - i;
166+
}
167+
Arrays.sort(arr);
168+
int m = 0;
169+
for (int i = 0; i < n; ++i) {
170+
if (i == 0 || arr[i] != arr[i - 1]) {
171+
arr[m++] = arr[i];
172+
}
173+
}
174+
BinaryIndexedTree tree = new BinaryIndexedTree(m);
175+
for (int i = 0; i < n; ++i) {
176+
int j = search(arr, nums[i] - i, m) + 1;
177+
long v = Math.max(tree.query(j), 0) + nums[i];
178+
tree.update(j, v);
179+
}
180+
return tree.query(m);
181+
}
182+
183+
private int search(int[] nums, int x, int r) {
184+
int l = 0;
185+
while (l < r) {
186+
int mid = (l + r) >> 1;
187+
if (nums[mid] >= x) {
188+
r = mid;
189+
} else {
190+
l = mid + 1;
191+
}
192+
}
193+
return l;
194+
}
195+
}
86196
```
87197

88198
### **C++**
89199

90200
```cpp
91-
201+
class BinaryIndexedTree {
202+
private:
203+
int n;
204+
vector<long long> c;
205+
const long long inf = 1e18;
206+
207+
public:
208+
BinaryIndexedTree(int n) {
209+
this->n = n;
210+
c.resize(n + 1, -inf);
211+
}
212+
213+
void update(int x, long long v) {
214+
while (x <= n) {
215+
c[x] = max(c[x], v);
216+
x += x & -x;
217+
}
218+
}
219+
220+
long long query(int x) {
221+
long long mx = -inf;
222+
while (x > 0) {
223+
mx = max(mx, c[x]);
224+
x -= x & -x;
225+
}
226+
return mx;
227+
}
228+
};
229+
230+
class Solution {
231+
public:
232+
long long maxBalancedSubsequenceSum(vector<int>& nums) {
233+
int n = nums.size();
234+
vector<int> arr(n);
235+
for (int i = 0; i < n; ++i) {
236+
arr[i] = nums[i] - i;
237+
}
238+
sort(arr.begin(), arr.end());
239+
arr.erase(unique(arr.begin(), arr.end()), arr.end());
240+
int m = arr.size();
241+
BinaryIndexedTree tree(m);
242+
for (int i = 0; i < n; ++i) {
243+
int j = lower_bound(arr.begin(), arr.end(), nums[i] - i) - arr.begin() + 1;
244+
long long v = max(tree.query(j), 0LL) + nums[i];
245+
tree.update(j, v);
246+
}
247+
return tree.query(m);
248+
}
249+
};
92250
```
93251
94252
### **Go**
95253
96254
```go
255+
const inf int = 1e18
256+
257+
type BinaryIndexedTree struct {
258+
n int
259+
c []int
260+
}
261+
262+
func NewBinaryIndexedTree(n int) BinaryIndexedTree {
263+
c := make([]int, n+1)
264+
for i := range c {
265+
c[i] = -inf
266+
}
267+
return BinaryIndexedTree{n: n, c: c}
268+
}
269+
270+
func (bit *BinaryIndexedTree) update(x, v int) {
271+
for x <= bit.n {
272+
bit.c[x] = max(bit.c[x], v)
273+
x += x & -x
274+
}
275+
}
276+
277+
func (bit *BinaryIndexedTree) query(x int) int {
278+
mx := -inf
279+
for x > 0 {
280+
mx = max(mx, bit.c[x])
281+
x -= x & -x
282+
}
283+
return mx
284+
}
285+
286+
func maxBalancedSubsequenceSum(nums []int) int64 {
287+
n := len(nums)
288+
arr := make([]int, n)
289+
for i, x := range nums {
290+
arr[i] = x - i
291+
}
292+
sort.Ints(arr)
293+
m := 0
294+
for i, x := range arr {
295+
if i == 0 || x != arr[i-1] {
296+
arr[m] = x
297+
m++
298+
}
299+
}
300+
arr = arr[:m]
301+
tree := NewBinaryIndexedTree(m)
302+
for i, x := range nums {
303+
j := sort.SearchInts(arr, x-i) + 1
304+
v := max(tree.query(j), 0) + x
305+
tree.update(j, v)
306+
}
307+
return int64(tree.query(m))
308+
}
309+
```
97310

311+
### **TypeScript**
312+
313+
```ts
314+
class BinaryIndexedTree {
315+
private n: number;
316+
private c: number[];
317+
318+
constructor(n: number) {
319+
this.n = n;
320+
this.c = Array(n + 1).fill(-Infinity);
321+
}
322+
323+
update(x: number, v: number): void {
324+
while (x <= this.n) {
325+
this.c[x] = Math.max(this.c[x], v);
326+
x += x & -x;
327+
}
328+
}
329+
330+
query(x: number): number {
331+
let mx = -Infinity;
332+
while (x > 0) {
333+
mx = Math.max(mx, this.c[x]);
334+
x -= x & -x;
335+
}
336+
return mx;
337+
}
338+
}
339+
340+
function maxBalancedSubsequenceSum(nums: number[]): number {
341+
const n = nums.length;
342+
const arr = Array(n).fill(0);
343+
for (let i = 0; i < n; ++i) {
344+
arr[i] = nums[i] - i;
345+
}
346+
arr.sort((a, b) => a - b);
347+
let m = 0;
348+
for (let i = 0; i < n; ++i) {
349+
if (i === 0 || arr[i] !== arr[i - 1]) {
350+
arr[m++] = arr[i];
351+
}
352+
}
353+
arr.length = m;
354+
const tree = new BinaryIndexedTree(m);
355+
const search = (nums: number[], x: number): number => {
356+
let [l, r] = [0, nums.length];
357+
while (l < r) {
358+
const mid = (l + r) >> 1;
359+
if (nums[mid] >= x) {
360+
r = mid;
361+
} else {
362+
l = mid + 1;
363+
}
364+
}
365+
return l;
366+
};
367+
for (let i = 0; i < n; ++i) {
368+
const j = search(arr, nums[i] - i) + 1;
369+
const v = Math.max(tree.query(j), 0) + nums[i];
370+
tree.update(j, v);
371+
}
372+
return tree.query(m);
373+
}
98374
```
99375

100376
### **...**

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /