可忽略恰好一个元素的二维最大子矩阵求解算法咨询
求解可忽略单个元素的二维最大子矩阵(时间复杂度接近O(m²n))
当然有可行的方案!我们可以基于经典的Kadane算法做扩展,把“允许忽略一个元素”的逻辑融入到一维问题的处理中,再推广到二维场景,整体时间复杂度可以控制在O(m²*n),和原二维最大子矩阵算法的复杂度几乎同阶,不会大幅升高。
核心思路拆解
常规二维最大子矩阵的解法是通过固定左右列,将每一行的列间元素求和压缩为一维数组,再用Kadane算法找该一维数组的最大子数组。要支持忽略单个元素,我们只需要修改一维Kadane的实现,让它能处理“允许跳过一个元素”的情况,再将这个扩展后的一维算法套入二维的列压缩流程即可。
第一步:扩展一维Kadane算法(支持跳过一个元素)
对于一维数组,我们维护两个状态变量(或数组)来跟踪两种情况:
dp_no_skip:表示以当前元素结尾,未跳过任何元素的最大子数组和dp_skip:表示以当前元素结尾,已经跳过一个元素的最大子数组和
状态转移方程如下:
dp_no_skip[i] = max(dp_no_skip[i-1] + arr[i], arr[i]) dp_skip[i] = max(dp_no_skip[i-1], dp_skip[i-1] + arr[i])
dp_no_skip的逻辑和普通Kadane一致:要么延续前序子数组,要么从当前元素重新开始dp_skip包含两种可能:要么跳过当前元素,直接复用前序未跳过的最大和;要么之前已经跳过一个元素,继续将当前元素加入子数组
遍历数组时,同步跟踪这两个状态的全局最大值,就能得到允许跳过一个元素的一维最大子数组和。这个扩展算法的时间复杂度仍然是O(n),和普通Kadane完全一致。
第二步:推广到二维场景
和常规解法一样,我们枚举所有左右列的组合(共O(m²)种,m为列数):
- 对每一种列组合,计算每一行从左列到右列的元素和,得到一维数组
row_sums(长度为n,n为行数) - 对
row_sums使用上述扩展Kadane算法,得到该列组合下允许跳过一个元素的最大子矩阵和 - 最终在所有列组合的结果中取最大值,即为整个问题的答案
时间复杂度分析
枚举列组合的时间是O(m²),每一次列组合处理需要:
- O(n)时间计算
row_sums - O(n)时间执行扩展Kadane算法
总时间复杂度为O(m²*(n + n)) = O(m²*n),和原二维最大子矩阵算法的复杂度完全同阶,没有大幅升高。
解决“确定忽略元素”的难点
你提到的核心难点——提前确定要忽略的元素——其实不需要刻意解决!这个扩展算法会在遍历过程中自动覆盖所有可能的跳过情况:
- 一维的
dp_skip状态转移已经考虑了跳过任意一个元素的可能性 - 结合二维的列枚举,相当于遍历了所有可能的子矩阵中跳过任意一个元素的场景,最终通过取最大值得到最优解
示例辅助理解
假设我们有一个3x3矩阵:
1 -2 3 4 -5 6 7 -8 9
当固定左列1、右列3时,row_sums为[2, 5, 8]:
dp_no_skip序列为[2, 7, 15]dp_skip序列为[0, 5, 13]
此时最大和为15(未跳过元素);如果row_sums是[-5, 2, -5],dp_skip的最大值会是2(跳过第一个或第三个元素),完全覆盖了最优的跳过场景。
内容的提问来源于stack exchange,提问作者Alex Borgue
相关产品推荐
相关产品推荐

