Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 9b9643e

Browse files
authored
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)