输入 :具有正负元素的二维数组NxN-矩阵。
输出 :任意大小的子矩阵,使得其总和在所有可能的子矩阵中最大。
要求 :算法复杂度为 O(N ^ 3)
历史: 在算法学家,拉里(Larry)和对Kadane算法的修改的帮助下,我设法 部分地 解决了该问题,该问题仅在Java中确定求和。 感谢 Ernesto ,他设法解决了剩下的问题,即确定矩阵的边界,即Ruby中的左上角,右下角。
关于恢复实际子矩阵,而不仅仅是恢复最大和,这就是我得到的。抱歉,我没有时间将我的代码转换为您的Java版本,因此我要在关键部分发表一些评论的Ruby代码
def max_contiguous_submatrix_n3(m) rows = m.count cols = rows ? m.first.count : 0 vps = Array.new(rows) for i in 0..rows vps[i] = Array.new(cols, 0) end for j in 0...cols vps[0][j] = m[0][j] for i in 1...rows vps[i][j] = vps[i-1][j] + m[i][j] end end max = [m[0][0],0,0,0,0] # this is the result, stores [max,top,left,bottom,right] # these arrays are used over Kadane sum = Array.new(cols) # obvious sum array used in Kadane pos = Array.new(cols) # keeps track of the beginning position for the max subseq ending in j for i in 0...rows for k in i...rows # Kadane over all columns with the i..k rows sum.fill(0) # clean both the sum and pos arrays for the upcoming Kadane pos.fill(0) local_max = 0 # we keep track of the position of the max value over each Kadane's execution # notice that we do not keep track of the max value, but only its position sum[0] = vps[k][0] - (i==0 ? 0 : vps[i-1][0]) for j in 1...cols value = vps[k][j] - (i==0 ? 0 : vps[i-1][j]) if sum[j-1] > 0 sum[j] = sum[j-1] + value pos[j] = pos[j-1] else sum[j] = value pos[j] = j end if sum[j] > sum[local_max] local_max = j end end # Kadane ends here # Here's the key thing # If the max value obtained over the past Kadane's execution is larger than # the current maximum, then update the max array with sum and bounds if sum[local_max] > max[0] # sum[local_max] is the new max value # the corresponding submatrix goes from rows i..k. # and from columns pos[local_max]..local_max # the array below contains [max_sum,top,left,bottom,right] max = [sum[local_max], i, pos[local_max], k, local_max] end end end return max # return the array with [max_sum,top,left,bottom,right] end
需要澄清的一些注意事项:
为了方便起见,我使用数组存储与结果有关的所有值。您可以只使用五个独立变量:max,top,left,bottom,right。在一行中分配给数组更容易,然后子例程将返回包含所有所需信息的数组。
如果您将此代码复制并粘贴到具有Ruby支持的启用文本高亮的编辑器中,您显然会更好地理解它。希望这可以帮助!