如何在 K 最大子数组和算法中返回具体的子数组区间
发布时间 - 2026-01-05 00:00:00 点击率:次本文介绍如何修改基于 kadane 算法扩展的 o(nk) 时间复杂度 k-最大子数组和代码,使其不仅能计算最大和,还能准确返回构成该和的 k 个不重叠连续子数组的起止索引(左闭右开)。
要从动态规划状态中还原实际子数组,核心思想是:在前向递推过程中记录决策路径(predecessor),再通过反向回溯重建解。原代码使用长度为 2k+1 的 best 数组模拟“交替包含/排除”状态(奇数下标表示当前处于某子数组内,偶数下标表示刚结束一个子数组),但未保存每一步的选择依据。我们需引入 preds 数组,在每次更新 best[interval_idx] 时标记该值是否来自“跳过当前元素”(即继承前一状态)——这正是回溯的关键分支点。
以下是完整可运行的增强版实现(依赖 numpy,但逻辑清晰、易于迁移至纯 Python):
import numpy as np
def solve_SO_with_intervals(test_seq, k=2):
"""
返回 k 个不重叠连续子数组的左闭右开区间列表,使总和最大。
示例:solve_SO_with_intervals([-1, 2, -1, 2, -1], k=2) → [(1, 4), (3, 5)]
注意:返回区间为 (start, end),满足 subarray = test_seq[start:end]
"""
n = len(test_seq)
if n == 0 or k <= 0:
return []
num_intervals = k * 2 + 1 # 状态数:0(空), 1(含第1段), 2(第1段结束), ..., 2k+1(第k段结束)
best = np.zeros(num_intervals, dtype=int)
# preds[i][j] = 1 表示在处理第 i 个元素后,状态 j 的最优值来自「不将 test_seq[i] 加入当前子数组」
# 即:best[j] 继承自 best[j-1](跳过开启/关闭决策)
preds = np.zeros((n, num_intervals), dtype=np.int8)
for seq_idx, val in enumerate(test_seq):
# 步骤1:对所有「包含」状态(奇数下标)累加当前值
for interval_idx in range(1, num_intervals, 2):
best[interval_idx] += val
# 步骤2:单调化 —— 若当前状态不如前一状态优,则继承前一状态,并记录决策
for interval_idx in range(1, num_intervals):
if best[interval_idx] < best[interval_idx - 1]:
best[interval_idx] = best[interval_idx - 1]
preds[seq_idx][interval_idx] = 1
else:
preds[seq_idx][interval_idx] = 0
# 步骤3:确定最终采用的状态(取所有「已结束」状态中的最大值,即偶数下标)
final_state = 0
for interval_idx in range(0, num_intervals, 2): # 只检查偶数:0,2,4,...,2k
if best[interval_idx] > best[final_state]:
final_state = interval_idx
# 步骤4:反向回溯构造区间
intervals = []
open_end = 0 # 当前待关闭子数组的右边界(初始未开启)
# 从最后一个元素开始倒序遍历
for seq_idx in range(n - 1, -1, -1):
if preds[seq_idx][final_state]:
# 决策为「跳过」,意味着此处发生了状态切换:
if final_state % 2 == 1: # 奇数状态:刚进入子数组 → 记录上一段 [seq_idx+1, open_end)
if open_end > seq_idx + 1: # 避免空区间
intervals.append((seq_idx + 1, open_end))
else: # 偶数状态:刚结束子数组 → 更新 open_end 为当前索引+1
open_end = seq_idx + 1
final_state -= 1 # 回退到前一状态
# 处理覆盖数组开头的情
况(final_state 可能仍为 1,表示第一段从索引 0 开始)
if final_state == 1 and open_end > 0:
intervals.append((0, open_end))
intervals.reverse()
return intervals关键注意事项:
- 区间为 左闭右开(Python 切片风格),例如 (1, 4) 对应 test_seq[1:4];
- 算法默认允许空子数组(和为 0),若全负则返回空列表 [];
- 回溯逻辑依赖 preds[seq_idx][state] 精确反映「是否因继承而放弃当前元素」,因此必须在 best[j]
- 实际应用中建议添加输入校验(如 k > n 时剪枝)和边界测试(空数组、单元素、k=0 等)。
调用示例:
print(solve_SO_with_intervals([-1, 2, -1, 2, -1], k=2)) # [(1, 4), (3, 5)] print(solve_SO_with_intervals([-1, 2, -1, 2, -1], k=1)) # [(1, 4)] print(solve_SO_with_intervals([5, -1, 3], k=2)) # [(0, 1), (2, 3)]
此方案将原始算法从纯数值优化升级为可解释的结构化输出,适用于调度、信号分段、金融时间序列分析等需定位关键片段的实际场景。
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
Claude怎样写结构化提示词_Claude结构化提示词写法【教程】
谷歌浏览器下载文件时中断怎么办 Google Chrome下载管理修复
图片制作网站免费软件,有没有免费的网站或软件可以将图片批量转为A4大小的pdf?
,怎么在广州志愿者网站注册?
Laravel如何创建自定义Artisan命令?(代码示例)
使用Dockerfile构建java web环境
如何在Windows环境下新建FTP站点并设置权限?
企业在线网站设计制作流程,想建设一个属于自己的企业网站,该如何去做?
厦门模型网站设计制作公司,厦门航空飞机模型掉色怎么办?
如何在阿里云完成域名注册与建站?
Laravel如何处理文件下载请求?(Response示例)
Swift中switch语句区间和元组模式匹配
Claude怎样写约束型提示词_Claude约束提示词写法【教程】
python中快速进行多个字符替换的方法小结
Laravel如何发送邮件和通知_Laravel邮件与通知系统发送步骤
Midjourney怎样加参数调细节_Midjourney参数调整技巧【指南】
如何实现建站之星域名转发设置?
Laravel如何发送系统通知?(Notification渠道示例)
Laravel如何处理CORS跨域问题_Laravel项目CORS配置与解决方案
Laravel如何实现API版本控制_Laravel API版本化路由设计策略
今日头条AI怎样推荐抢票工具_今日头条AI抢票工具推荐算法与筛选【技巧】
Laravel Eloquent性能优化技巧_Laravel N+1查询问题解决
学生网站制作软件,一个12岁的学生写小说,应该去什么样的网站?
如何自定义safari浏览器工具栏?个性化设置safari浏览器界面教程【技巧】
Python正则表达式进阶教程_复杂匹配与分组替换解析
laravel怎么通过契约(Contracts)编程_laravel契约(Contracts)编程方法
网页设计与网站制作内容,怎样注册网站?
php中::能调用final静态方法吗_final修饰静态方法调用规则【解答】
专业商城网站制作公司有哪些,pi商城官网是哪个?
公司门户网站制作流程,华为官网怎么做?
html5源代码发行怎么设置权限_访问权限控制方法与实践【指南】
Laravel怎么实现模型属性的自动加密
网站制作企业,网站的banner和导航栏是指什么?
如何用美橙互联一键搭建多站合一网站?
Laravel如何使用Collections进行数据处理?(实用方法示例)
Laravel API资源类怎么用_Laravel API Resource数据转换
如何快速使用云服务器搭建个人网站?
JS碰撞运动实现方法详解
微信公众帐号开发教程之图文消息全攻略
零基础网站服务器架设实战:轻量应用与域名解析配置指南
实例解析Array和String方法
Windows Hello人脸识别突然无法使用
Laravel如何使用Scope本地作用域_Laravel模型常用查询逻辑封装技巧【手册】
Laravel Admin后台管理框架推荐_Laravel快速开发后台工具
Laravel Eloquent访问器与修改器是什么_Laravel Accessors & Mutators数据处理技巧
微信小程序 canvas开发实例及注意事项
弹幕视频网站制作教程下载,弹幕视频网站是什么意思?
北京专业网站制作设计师招聘,北京白云观官方网站?
北京的网站制作公司有哪些,哪个视频网站最好?
Python进程池调度策略_任务分发说明【指导】


况(final_state 可能仍为 1,表示第一段从索引 0 开始)
if final_state == 1 and open_end > 0:
intervals.append((0, open_end))
intervals.reverse()
return intervals