Skip to content

Commit 02499d0

Browse files
committed
增加题解
1 parent 11bf594 commit 02499d0

File tree

3 files changed

+116
-1
lines changed

3 files changed

+116
-1
lines changed

docs/00_preface/00_05_solutions_list.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# LeetCode 题解(已完成 1302 道)
1+
# LeetCode 题解(已完成 1303 道)
22

33
### 第 1 ~ 99 题
44

@@ -633,6 +633,7 @@
633633
| [0641. 设计循环双端队列](https://leetcode.cn/problems/design-circular-deque/) | [题解](https://github.com/ITCharge/AlgoNote/tree/main/docs/solutions/0600-0699/design-circular-deque.md) | 设计、队列、数组、链表 | 中等 |
634634
| [0642. 设计搜索自动补全系统](https://leetcode.cn/problems/design-search-autocomplete-system/) | [题解](https://github.com/ITCharge/AlgoNote/tree/main/docs/solutions/0600-0699/design-search-autocomplete-system.md) | 深度优先搜索、设计、字典树、字符串、数据流、排序、堆(优先队列) | 困难 |
635635
| [0643. 子数组最大平均数 I](https://leetcode.cn/problems/maximum-average-subarray-i/) | [题解](https://github.com/ITCharge/AlgoNote/tree/main/docs/solutions/0600-0699/maximum-average-subarray-i.md) | 数组、滑动窗口 | 简单 |
636+
| [0644. 子数组最大平均数 II](https://leetcode.cn/problems/maximum-average-subarray-ii/) | [题解](https://github.com/ITCharge/AlgoNote/tree/main/docs/solutions/0600-0699/maximum-average-subarray-ii.md) | 数组、二分查找、前缀和 | 困难 |
636637
| [0645. 错误的集合](https://leetcode.cn/problems/set-mismatch/) | [题解](https://github.com/ITCharge/AlgoNote/tree/main/docs/solutions/0600-0699/set-mismatch.md) | 位运算、数组、哈希表、排序 | 简单 |
637638
| [0646. 最长数对链](https://leetcode.cn/problems/maximum-length-of-pair-chain/) | [题解](https://github.com/ITCharge/AlgoNote/tree/main/docs/solutions/0600-0699/maximum-length-of-pair-chain.md) | 贪心、数组、动态规划、排序 | 中等 |
638639
| [0647. 回文子串](https://leetcode.cn/problems/palindromic-substrings/) | [题解](https://github.com/ITCharge/AlgoNote/tree/main/docs/solutions/0600-0699/palindromic-substrings.md) | 双指针、字符串、动态规划 | 中等 |

docs/solutions/0600-0699/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
- [0641. 设计循环双端队列](https://github.com/ITCharge/AlgoNote/tree/main/docs/solutions/0600-0699/design-circular-deque.md)
3030
- [0642. 设计搜索自动补全系统](https://github.com/ITCharge/AlgoNote/tree/main/docs/solutions/0600-0699/design-search-autocomplete-system.md)
3131
- [0643. 子数组最大平均数 I](https://github.com/ITCharge/AlgoNote/tree/main/docs/solutions/0600-0699/maximum-average-subarray-i.md)
32+
- [0644. 子数组最大平均数 II](https://github.com/ITCharge/AlgoNote/tree/main/docs/solutions/0600-0699/maximum-average-subarray-ii.md)
3233
- [0645. 错误的集合](https://github.com/ITCharge/AlgoNote/tree/main/docs/solutions/0600-0699/set-mismatch.md)
3334
- [0646. 最长数对链](https://github.com/ITCharge/AlgoNote/tree/main/docs/solutions/0600-0699/maximum-length-of-pair-chain.md)
3435
- [0647. 回文子串](https://github.com/ITCharge/AlgoNote/tree/main/docs/solutions/0600-0699/palindromic-substrings.md)
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
# [0644. 子数组最大平均数 II](https://leetcode.cn/problems/maximum-average-subarray-ii/)
2+
3+
- 标签:数组、二分查找、前缀和
4+
- 难度:困难
5+
6+
## 题目链接
7+
8+
- [0644. 子数组最大平均数 II - 力扣](https://leetcode.cn/problems/maximum-average-subarray-ii/)
9+
10+
## 题目大意
11+
12+
**描述**
13+
14+
给你一个包含 $n$ 个整数的数组 $nums$,和一个整数 $k$。
15+
16+
**要求**
17+
18+
找出 **长度大于等于** $k$ 且含最大平均值的连续子数组。并输出这个最大平均值。任何计算误差小于 $10^{-5}$ 的结果都将被视为正确答案。
19+
20+
**说明**
21+
22+
- $n == nums.length$。
23+
- $1 \le k \le n \le 10^4$。
24+
- $-10^4 \le nums[i] \le 10^4$。
25+
26+
**示例**
27+
28+
- 示例 1:
29+
30+
```python
31+
输入:nums = [1,12,-5,-6,50,3], k = 4
32+
输出:12.75000
33+
解释:
34+
- 当长度为 4 的时候,连续子数组平均值分别为 [0.5, 12.75, 10.5],其中最大平均值是 12.75
35+
- 当长度为 5 的时候,连续子数组平均值分别为 [10.4, 10.8],其中最大平均值是 10.8
36+
- 当长度为 6 的时候,连续子数组平均值分别为 [9.16667],其中最大平均值是 9.16667
37+
当取长度为 4 的子数组(即,子数组 [12, -5, -6, 50])的时候,可以得到最大的连续子数组平均值 12.75,所以返回 12.75
38+
根据题目要求,无需考虑长度小于 4 的子数组。
39+
```
40+
41+
- 示例 2:
42+
43+
```python
44+
输入:nums = [5], k = 1
45+
输出:5.00000
46+
```
47+
48+
## 解题思路
49+
50+
### 思路 1:二分查找 + 前缀和
51+
52+
这道题目要求找到长度大于等于 $k$ 的子数组的最大平均值。
53+
54+
**核心思路**
55+
56+
- 使用二分查找来确定最大平均值。
57+
- 对于一个给定的平均值 $mid$,判断是否存在长度大于等于 $k$ 的子数组,其平均值大于等于 $mid$。
58+
- 判断方法:将数组中每个元素减去 $mid$,如果存在长度大于等于 $k$ 的子数组和大于等于 $0$,则说明存在平均值大于等于 $mid$ 的子数组。
59+
60+
**算法步骤**
61+
62+
1. 二分查找的范围是 $[min(nums), max(nums)]$。
63+
2. 对于每个 $mid$,将数组中每个元素减去 $mid$,得到新数组 $arr$。
64+
3. 使用前缀和 + 滑动窗口,判断是否存在长度大于等于 $k$ 的子数组和大于等于 $0$。
65+
4. 如果存在,说明最大平均值在 $[mid, right]$ 范围内;否则在 $[left, mid]$ 范围内。
66+
5. 重复步骤 2-4,直到 $left$ 和 $right$ 的差值小于 $10^{-5}$。
67+
68+
### 思路 1:代码
69+
70+
```python
71+
class Solution:
72+
def findMaxAverage(self, nums: List[int], k: int) -> float:
73+
def check(mid):
74+
"""判断是否存在长度 >= k 的子数组,平均值 >= mid"""
75+
# 将数组中每个元素减去 mid,计算前缀和
76+
n = len(nums)
77+
prefix_sum = 0
78+
prev_sum = 0 # 前 i-k 个元素的前缀和
79+
min_prev_sum = 0 # 前 i-k 个元素中的最小前缀和
80+
81+
for i in range(n):
82+
prefix_sum += nums[i] - mid
83+
84+
# 长度至少为 k
85+
if i >= k - 1:
86+
# prefix_sum - min_prev_sum 表示某个长度 >= k 的子数组和
87+
if prefix_sum - min_prev_sum >= 0:
88+
return True
89+
90+
# 更新 prev_sum 和 min_prev_sum
91+
# prev_sum 是前 i-k+1 个元素的前缀和
92+
prev_sum += nums[i - k + 1] - mid
93+
min_prev_sum = min(min_prev_sum, prev_sum)
94+
95+
return False
96+
97+
# 二分查找
98+
left, right = min(nums), max(nums)
99+
100+
while right - left > 1e-5:
101+
mid = (left + right) / 2
102+
if check(mid):
103+
left = mid
104+
else:
105+
right = mid
106+
107+
return left
108+
```
109+
110+
### 思路 1:复杂度分析
111+
112+
- **时间复杂度**:$O(n \log(max - min))$,其中 $n$ 是数组长度,$max$ 和 $min$ 分别是数组的最大值和最小值。二分查找的次数为 $O(\log(max - min))$,每次检查需要 $O(n)$ 时间。
113+
- **空间复杂度**:$O(1)$。只使用了常数额外空间。

0 commit comments

Comments
 (0)