363. Max Sum of Rectangle No Larger Than K

来源:互联网 发布:淘宝话费充值店铺介绍 编辑:程序博客网 时间:2024/06/05 23:39

Given a non-empty 2D matrix matrix and an integer k, find the max sum of a rectangle in the matrix such that its sum is no larger than k.

Example:

Given matrix = [  [1,  0, 1],  [0, -2, 3]]k = 2

The answer is 2. Because the sum of rectangle [[0, 1], [-2, 3]] is 2 and 2 is the max number no larger than k (k = 2).

Note:

  1. The rectangle inside the matrix must have an area > 0.

  1. What if the number of rows is much larger than the number of columns?

思路:先考虑一维数组的最大Rectangle,因为有负数,所以O(N)的背包算法不行,brute force是O(N^2),那我们可以可以把一维数组的这个问题用O(N*logN)的复杂度解决呢?答案是可以的,
遍历一遍,running sum,遍历到i位置时,最需要的是:sum[i]-target出现在之前的sum[0...i]中,但不一定找得到,所以我们只能找比它小一点的,但是是最大的那个数,这就决定了我们要用的数据结构,不是用HashTable,,而是Tree
/* * 因为要找的数可能并不在数组里,只能找比它小的最大的数 * 这也决定了我们要用的数据结构不是HashTable,而是Tree */public class oneDTest {public static void main(String[] args) {int[] a = new int[]{2,2,-1};System.out.println(MostNoLargerThan(a, 0));}// since there could be negative number, packet algorithm will not work// but we can do it in NlogN using a treeprivate static int MostNoLargerThan(int[] a, int target) {TreeSet<Integer> set = new TreeSet<Integer>();int sum = 0;set.add(sum);int ret = Integer.MIN_VALUE;for(int i : a){sum += i;Integer ceiling = set.ceiling(sum-target);if(ceiling != null)ret = Math.max(ret, sum-ceiling);set.add(sum);}return ret;}}


有了一维数组,二维数组无非就是把二维转换成一维罢了
public class Solution {    public int maxSumSubmatrix(int[][] matrix, int k) {    int max = Integer.MIN_VALUE;        // 先确定横着的2刀切的位置    for(int i=0; i<matrix.length; i++) {    int[] sum = new int[matrix[0].length];    for(int j=i; j<matrix.length; j++) {    for(int q=0; q<matrix[0].length; q++)    sum[q] += matrix[j][q];    max = Math.max(max, MostNoLargerThan(sum, k));    }    }    return max;    }        private static int MostNoLargerThan(int[] a, int target) {TreeSet<Integer> set = new TreeSet<Integer>();int sum = 0;set.add(sum);int ret = Integer.MIN_VALUE;for(int i : a){sum += i;Integer ceiling = set.ceiling(sum-target);if(ceiling != null)ret = Math.max(ret, sum-ceiling);set.add(sum);}return ret;}}


其实最开始的时候,想用二分来着,因为好多求min(max)的问题就是用二分逼近答案的,但是这个题貌似没有明显的min(max),max(min)的意思

0 0
原创粉丝点击