在O(n^2)内寻找矩阵A中 A(c,d) - A(a,b) 的最大值, c > a 且 d > b.

来源:互联网 发布:qq抢红包源码 编辑:程序博客网 时间:2024/06/06 03:07

参考:

http://www.careercup.com/question?id=5818131813498880


题目:

Given an n x n matrix A(i,j) of integers, find maximum value A(c,d) - A(a,b) over all choices of indexes such that both c > a and d > b. Required complexity: O(n^2)


解题思路:


1.把二维的矩阵想象成一维的数组,用O(n)的实现找到一维数组中A(m)-A(n) 的最大值,要求m>n

=》解法:

$min_value = $A[0];for($i=1; $i<$N; $i++) {    // A[i] - A[j] is maximal, when A[j] is minimal value from {A[0], A[1],.., A[i-1]}    $res = max($res, $A[i] - $min_value);    $min_value = min($min_value, $A[$i]);}echo $res;


同理,二维的矩阵也是类似的:

2.由于有限定条件c>a &&d>b,所以想到从对角线去遍历矩阵 



3.在一维的条件下保证m>n是容易的,现在的问题就是如何在二维条件下也能保证 c>a &&d>b

构造一个“备忘录”数组maxtrix_min[i][j],代表以(0,0)为左上角坐标,(i,j)为右下角坐标为的矩阵中的最小值。

这里用到了“记录法”,由于两层for循环后,以(i-1,j)为右下角的矩阵的最小值已经被记录了,以(i,j-1)为右下角的矩阵的最小值也已经被记录了,最后比较得出的结果就是以(0,0)为左上角坐标,(i,j)为右下角坐标的i*j矩阵的最小值min_value。然后,通过动态规划

$max_diff = max ($max_diff, $m[$i+1][$j+1] - $min_value );


即可在O(N^2)的时间复杂度内算出结果。


php实现:

<?php$m = array (array(9,1,3,6),array(5,2,2,3),array(7,17,16,11),array(6,1,8,15));$n = count($m);$max_diff = $m[1][1] - $m[0][0];$matrix_min = array();for($i = 0; $i < $n-1; $i ++) {for($j = 0; $j < $n-1; $j ++) {if ($i == 0 && $j == 0) {$min_value = $m [0] [0];} elseif ($i == 0 && $j > 0) {$min_value = min ($m[$i][$j], $m[0][$i]);} elseif ($j == 0 && $i > 0) {$min_value = min ($m[$i][$j], $matrix_min[0][$j]);} else {$min_value = min ($m[$i][$j], $matrix_min[$i-1][$j], $matrix_min[$i][$j-1]);}$matrix_min[$i][$j] = $min_value;$max_diff = max ($max_diff, $m[$i+1][$j+1] - $min_value );echo "i:$i j:$j min_value:$min_value:".$matrix_min[$i][$j]." max_diff:$max_diff" . "<br>";}}


打印输出:



致谢:

@czxttkl

@buptpatriot