1. 东华OJ18~21题目解析与实战攻略
作为一名在算法竞赛领域摸爬滚打多年的老选手,我深知东华OJ平台题目的独特风格。18~21这组题目看似简单,实则暗藏玄机,特别适合用来检验基础算法的掌握程度。今天我就带大家逐题拆解,分享我的解题思路和优化技巧。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 题目18:最大子段和进阶版
2.1 问题重述
给定一个包含n个整数的序列,要求找出连续子序列的最大和。与经典问题不同的是,本题增加了限制条件:子序列长度不能超过k。
2.2 常规解法分析
最直观的暴力解法时间复杂度为O(nk),当n和k较大时(比如n=1e5,k=1e3)就会超时。我最初尝试用前缀和优化:
python复制max_sum = -float('inf')
prefix = [0]*(n+1)
for i in range(1, n+1):
prefix[i] = prefix[i-1] + nums[i-1]
for j in range(max(0, i-k), i):
max_sum = max(max_sum, prefix[i]-prefix[j])
这个解法虽然比纯暴力稍好,但最坏情况下仍是O(nk)复杂度。
2.3 单调队列优化
经过研究,我发现可以用单调队列将复杂度降到O(n)。核心思路是维护一个存储前缀和索引的队列,保证队列中的前缀和单调递增:
python复制from collections import deque
def maxSubarray(nums, k):
q = deque()
prefix = [0]*(len(nums)+1)
res = -float('inf')
for i in range(len(nums)+1):
if i > 0:
prefix[i] = prefix[i-1] + nums[i-1]
while q and i - q[0] > k:
q.popleft()
if q:
res = max(res, prefix[i] - prefix[q[0]])
while q and prefix[i] <= prefix[q[-1]]:
q.pop()
q.append(i)
return res
关键技巧:队列中存储的是前缀和数组的索引而非值,这样既能控制窗口大小,又能快速获取最小前缀和。
3. 题目19:特殊排列计数
3.1 问题描述
给定n个不同的元素,计算满足特定相邻条件的排列数量。具体来说,任意两个相邻元素的差值不能等于某个给定值d。
3.2 动态规划解法
这类排列计
