青训营X豆包MarsCode 技术训练营第一课 - 77题 & 第一篇刷题笔记| 豆包MarsCode AI 刷题
之前以为只用刷题 + 系统里面run,没看到还要发布,于是第一篇就此诞生啦~
由于我也不是什么代码big佬,感觉就从题库里面挑点经典题型来做归纳提升吧~
今日topic:滑动窗口其之一
是不是应该先不说题型呢(
原题目
在番茄小说的书籍中,编辑小S正在寻找精彩的连续章节以进行特色展示。每个章节都有各自的文字数量,编辑希望选出的连续章节总字数不超过 k。在这些连续章节中,除了第一章和最后一章,任何字数多于前后章节的章节都被视为优质章节。编辑的目标是挑选出尽可能多的优质章节,同时满足总字数限制。
例如,假设章节字数为
[1000, 3000, 2000, 4000, 3000, 2000, 4000, 2000],给定的字数上限 k 为 15000。一种优选方案是选择从第1章到第5章,其中第2章和第4章是优质章节。
抽象关键词:想要挑选出一些连续章节进行特色展示。这些章节不仅要满足总字数不超过 k 的限制,还要尽可能多地包含优质章节。
- 优质章节,就是字数比前后章节都多的章节。
很常见的约束条件,用来约束什么能够进出窗口 or break掉
题目类型
这个题目属于数组与滑动窗口的范畴,优化也不用怎么优化。
整体思路
目标是找到一个连续的章节区间,使得区间内的优质章节数量最多,同时区间内的总字数不超过 k
- 经典做法即可:我们可以使用双指针(左右指针)来表示这个区间,通过不断调整指针的位置来寻找最优解。
代码分块解析
- 变量采用以下:
left和right分别表示区间的左右边界。current_sum用于记录当前窗口的总字数。max_quality_count记录当前找到的最大优质章节数量。best_left和best_right记录最优解的左右边界。
- 扩大窗口:
- 使用
right指针遍历数组,将当前章节的字数加入current_sum。
- 使用
- 缩小窗口:
- 当
current_sum超过 k 时,通过left指针缩小窗口,直到current_sum小于等于 k。
- 当
- 计算优质章节数量:
- 在当前窗口内,遍历
left + 1到right - 1的章节,判断是否为优质章节。
- 在当前窗口内,遍历
- 更新最优解:
- 如果当前窗口的优质章节数量大于
max_quality_count,则更新最优解。
- 如果当前窗口的优质章节数量大于
- 移动右指针:
- 继续寻找下一个可能的解。
整体代码如下:
def solution(n, k, array_a):
left = 0
right = 0
current_sum = 0
max_quality_count = 0
best_left = 0
best_right = 0
while right < n:
# 扩大窗口
current_sum += array_a[right]
# 如果当前窗口的字数总和超过 k,缩小窗口
while current_sum > k:
current_sum -= array_a[left]
left += 1
# 计算当前窗口内的优质章节数量
quality_count = 0
for i in range(left + 1, right):
if array_a[i] > array_a[i - 1] and array_a[i] > array_a[i + 1]:
quality_count += 1
# 更新最大优质章节数量和对应的起始、结束章节
if quality_count > max_quality_count:
max_quality_count = quality_count
best_left = left
best_right = right
# 移动右指针
right += 1
# 返回结果
return f"{max_quality_count + 1},{best_left + 1},{best_right + 1}"
if __name__ == "__main__":
# You can add more test cases here
print(solution(8, 15000, [1000, 3000, 2000, 4000, 3000, 2000, 4000, 2000]) == "2,1,5" )
print(solution(8, 15000, [2000, 5000, 2000, 1000, 4000, 2000, 4000, 3000]) == "2,4,8" )
总结
今日第一篇,见我第一年。滑动窗口现,编不出来鸟。
(PS:写一篇还真累啊,吭哧吭哧去除代码才超700字)