LeetCode 363. Max Sum of Rectangle No Larger Than K

363. Max Sum of Rectangle No Larger Than K

Hard

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:

Input: matrix = [[1,0,1],[0,-2,3]], k = 2
Output: 2
Explanation: Because the sum of rectangle [[0, 1], [-2, 3]] is 2,
and 2 is the max number no larger than k (k = 2).
Note:

The rectangle inside the matrix must have an area > 0.
What if the number of rows is much larger than the number of columns?

题意

给定两个数组,求数组的交集,如果交集中的元素在两个数组中均多次出现,则取出现次数的较小值放入交集数组

思路

暴力法的时间复杂度为O(m2n2). 现假设m < n, 考虑优化。将二维问题转化为m2个一维问题,即给定数组nums[0:n],求最大的不超过k的连续子列和(其中nums是第i行到第j行的行和,共m2个)。
注意到连续子列和conSum[i:j] = sum[0:j] - sum[0:i] <= k,因此求不超过k的连续子列和等价于给定sum[0:j],在0, sum[0:1], sum[0:2], …, sum[0:j-1]中求(sum[0:j] - k)的最小上界sum[0:i]. 用二叉树维护sum[0:i]的序列,插入、查找时间复杂度均为O(logn),因此一维问题的时间复杂度从O(n^2)降为O(nlogn). 总的时间复杂度为O(m^2nlogn).

代码

class Solution {
    public int maxSumSubmatrix(int[][] matrix, int k) {
        int row = matrix.length;
        if (row == 0) {
            return 0;
        }
        int col = matrix[0].length;
        if (col == 0) {
            return 0;
        }
        int m = Math.min(row, col), n = Math.max(row, col), i = 0, j = 0, t = 0, ans = Integer.MIN_VALUE;
        boolean rowLarge = row > col;
        for (i=0; i<m; ++i) {
            int[] arr = new int[n]; // sum(i:j, k)
            for (j=i; j>=0; --j) {
                TreeSet<Integer> set = new TreeSet<>();
                int val = 0;        // sum(i:j, 0:k)
                set.add(0);
                for (t=0; t<n; ++t) {
                    arr[t] += rowLarge? matrix[t][j]: matrix[j][t];
                    val += arr[t];
                    Integer ceil = set.ceiling(val - k);
                    if (ceil != null) {
                        ans = Math.max(ans, val - ceil);
                    }
                    set.add(val);
                }
            }
        }
        return ans;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值