Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion solution/3000-3099/3063.Linked List Frequency/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

<!-- 这里写题目描述 -->

<p>给定包含 <code>k</code> 个&nbsp;<strong>不同&nbsp;</strong>元素的链表的&nbsp;<code>head</code>&nbsp;节点,返回包含给定链表中每个 <strong>不同元素</strong> 以 <strong>任何顺序</strong> 出现的 <span data-keyword="frequency-linkedlist">频率</span> 的长度为&nbsp;<code>k</code>&nbsp;的链表的头节点。</p>
<p>给定包含 <code>k</code> 个&nbsp;<strong>不同&nbsp;</strong>元素的链表的&nbsp;<code>head</code>&nbsp;节点,创建一个长度为&nbsp;<code>k</code>&nbsp;的链表,包含给定链表中每个 <strong>不同元素</strong> 以 <strong>任何顺序</strong> 出现的 <span data-keyword="frequency-linkedlist">频率</span>&nbsp;。返回这个链表的头节点。</p>

<p>&nbsp;</p>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

[English Version](/solution/3000-3099/3073.Maximum%20Increasing%20Triplet%20Value/README_EN.md)

<!-- tags: -->
<!-- tags:数组,有序集合 -->

## 题目描述

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

[中文文档](/solution/3000-3099/3073.Maximum%20Increasing%20Triplet%20Value/README.md)

<!-- tags: -->
<!-- tags:Array,Ordered Set -->

## Description

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

[English Version](/solution/3000-3099/3074.Apple%20Redistribution%20into%20Boxes/README_EN.md)

<!-- tags: -->
<!-- tags:贪心,数组,排序 -->

## 题目描述

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

[中文文档](/solution/3000-3099/3074.Apple%20Redistribution%20into%20Boxes/README.md)

<!-- tags: -->
<!-- tags:Greedy,Array,Sorting -->

## Description

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

[English Version](/solution/3000-3099/3075.Maximize%20Happiness%20of%20Selected%20Children/README_EN.md)

<!-- tags: -->
<!-- tags:贪心,数组,排序 -->

## 题目描述

Expand Down Expand Up @@ -121,6 +121,18 @@ func maximumHappinessSum(happiness []int, k int) (ans int64) {
}
```

```ts
function maximumHappinessSum(happiness: number[], k: number): number {
happiness.sort((a, b) => b - a);
let ans = 0;
for (let i = 0; i < k; ++i) {
const x = happiness[i] - i;
ans += Math.max(x, 0);
}
return ans;
}
```

<!-- tabs:end -->

<!-- end -->
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

[中文文档](/solution/3000-3099/3075.Maximize%20Happiness%20of%20Selected%20Children/README.md)

<!-- tags: -->
<!-- tags:Greedy,Array,Sorting -->

## Description

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

[English Version](/solution/3000-3099/3076.Shortest%20Uncommon%20Substring%20in%20an%20Array/README_EN.md)

<!-- tags: -->
<!-- tags:字典树,数组,哈希表,字符串 -->

## 题目描述

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

[中文文档](/solution/3000-3099/3076.Shortest%20Uncommon%20Substring%20in%20an%20Array/README.md)

<!-- tags: -->
<!-- tags:Trie,Array,Hash Table,String -->

## Description

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

[English Version](/solution/3000-3099/3077.Maximum%20Strength%20of%20K%20Disjoint%20Subarrays/README_EN.md)

<!-- tags: -->
<!-- tags:数组,动态规划,前缀和 -->

## 题目描述

Expand Down Expand Up @@ -58,24 +58,150 @@

## 解法

### 方法一
### 方法一:动态规划

对于第 $i$ 个数 $nums[i - 1]$,如果它被选择,且位于第 $j$ 个子数组,那么它对答案的贡献是 $nums[i - 1] \times (k - j + 1) \times (-1)^{j+1}$,我们不妨将 $(-1)^{j+1}$ 记为 $sign$,那么它对答案的贡献是 $sign \times nums[i - 1] \times (k - j + 1)$。

我们定义 $f[i][j][0]$ 表示从前 $i 个数中选择 $j$ 个子数组,且第 $i$ 个数不被选的最大能量值,定义 $f[i][j][1]$ 表示从前 $i$ 个数中选择 $j$ 个子数组,且第 $i$ 个数被选的最大能量值。初始时 $f[0][0][1] = 0$,其余的值都是 $-\infty$。

当 $i > 0$ 时,我们考虑 $f[i][j]$ 如何进行状态转移。

如果第 $i$ 个数不被选,那么第 $i-1$ 个数既可以被选,也可以不被选,所以 $f[i][j][0] = \max(f[i-1][j][0], f[i-1][j][1])$。

如果第 $i$ 个数被选,此时如果第 $i-1$ 个数与第 $i$ 个数位于同一个子数组中,那么 $f[i][j][1] = \max(f[i][j][1], f[i-1][j][1] + sign \times nums[i-1] \times (k - j + 1))$,否则 $f[i][j][1] = \max(f[i][j][1], \max(f[i-1][j-1][0], f[i-1][j-1][1]) + sign \times nums[i-1] \times (k - j + 1))$。我们取这两种情况的最大值作为 $f[i][j][1]$。

最终答案是 $\max(f[n][k][0], f[n][k][1])$。

时间复杂度 $O(n \times k)$,空间复杂度 $O(n \times k)$。其中 $n$ 是数组 $nums$ 的长度。

<!-- tabs:start -->

```python

class Solution:
def maximumStrength(self, nums: List[int], k: int) -> int:
n = len(nums)
f = [[[-inf, -inf] for _ in range(k + 1)] for _ in range(n + 1)]
f[0][0][0] = 0
for i, x in enumerate(nums, 1):
for j in range(k + 1):
sign = 1 if j & 1 else -1
f[i][j][0] = max(f[i - 1][j][0], f[i - 1][j][1])
f[i][j][1] = max(f[i][j][1], f[i - 1][j][1] + sign * x * (k - j + 1))
if j:
f[i][j][1] = max(
f[i][j][1], max(f[i - 1][j - 1]) + sign * x * (k - j + 1)
)
return max(f[n][k])
```

```java

class Solution {
public long maximumStrength(int[] nums, int k) {
int n = nums.length;
long[][][] f = new long[n + 1][k + 1][2];
for (int i = 0; i <= n; i++) {
for (int j = 0; j <= k; j++) {
Arrays.fill(f[i][j], Long.MIN_VALUE / 2);
}
}
f[0][0][0] = 0;
for (int i = 1; i <= n; i++) {
int x = nums[i - 1];
for (int j = 0; j <= k; j++) {
long sign = (j & 1) == 1 ? 1 : -1;
long val = sign * x * (k - j + 1);
f[i][j][0] = Math.max(f[i - 1][j][0], f[i - 1][j][1]);
f[i][j][1] = Math.max(f[i][j][1], f[i - 1][j][1] + val);
if (j > 0) {
long t = Math.max(f[i - 1][j - 1][0], f[i - 1][j - 1][1]) + val;
f[i][j][1] = Math.max(f[i][j][1], t);
}
}
}
return Math.max(f[n][k][0], f[n][k][1]);
}
}
```

```cpp

class Solution {
public:
long long maximumStrength(vector<int>& nums, int k) {
int n = nums.size();
long long f[n + 1][k + 1][2];
memset(f, -0x3f3f3f3f3f3f3f3f, sizeof(f));
f[0][0][0] = 0;
for (int i = 1; i <= n; i++) {
int x = nums[i - 1];
for (int j = 0; j <= k; j++) {
long long sign = (j & 1) == 1 ? 1 : -1;
long long val = sign * x * (k - j + 1);
f[i][j][0] = max(f[i - 1][j][0], f[i - 1][j][1]);
f[i][j][1] = max(f[i][j][1], f[i - 1][j][1] + val);
if (j > 0) {
long long t = max(f[i - 1][j - 1][0], f[i - 1][j - 1][1]) + val;
f[i][j][1] = max(f[i][j][1], t);
}
}
}
return max(f[n][k][0], f[n][k][1]);
}
};
```

```go
func maximumStrength(nums []int, k int) int64 {
n := len(nums)
f := make([][][]int64, n+1)
const inf int64 = math.MinInt64 / 2
for i := range f {
f[i] = make([][]int64, k+1)
for j := range f[i] {
f[i][j] = []int64{inf, inf}
}
}
f[0][0][0] = 0
for i := 1; i <= n; i++ {
x := nums[i-1]
for j := 0; j <= k; j++ {
sign := int64(-1)
if j&1 == 1 {
sign = 1
}
val := sign * int64(x) * int64(k-j+1)
f[i][j][0] = max(f[i-1][j][0], f[i-1][j][1])
f[i][j][1] = max(f[i][j][1], f[i-1][j][1]+val)
if j > 0 {
t := max(f[i-1][j-1][0], f[i-1][j-1][1]) + val
f[i][j][1] = max(f[i][j][1], t)
}
}
}
return max(f[n][k][0], f[n][k][1])
}
```

```ts
function maximumStrength(nums: number[], k: number): number {
const n: number = nums.length;
const f: number[][][] = Array.from({ length: n + 1 }, () =>
Array.from({ length: k + 1 }, () => [-Infinity, -Infinity]),
);
f[0][0][0] = 0;
for (let i = 1; i <= n; i++) {
const x: number = nums[i - 1];
for (let j = 0; j <= k; j++) {
const sign: number = (j & 1) === 1 ? 1 : -1;
const val: number = sign * x * (k - j + 1);
f[i][j][0] = Math.max(f[i - 1][j][0], f[i - 1][j][1]);
f[i][j][1] = Math.max(f[i][j][1], f[i - 1][j][1] + val);
if (j > 0) {
f[i][j][1] = Math.max(f[i][j][1], Math.max(...f[i - 1][j - 1]) + val);
}
}
}
return Math.max(...f[n][k]);
}
```

<!-- tabs:end -->
Expand Down
Loading