leetcode 363. Max Sum of Rectangle No Larger Than K

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:

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

转化成前缀和归并排序+双指针查找前缀和之差接近k的数,或者前缀和+BST查找前缀和之差接近k的数。

时间复杂度O(n^3logn).

前缀和+归并排序+双指针.

class Solution {
    public int maxSumSubmatrix(int[][] m, int k) {
        int max=Integer.MIN_VALUE;
        for(int i=0;i<m[0].length;i++){
            int[] arr=new int[m.length];
            for(int j=i;j<m[0].length;j++){
                for(int n=0;n<m.length;n++){
                    arr[n]+=m[n][j];
                }
                int[] sum=new int[m.length];
                for(int n=0;n<m.length;n++){
                    if(n==0) sum[0]=arr[0];
                    else sum[n]=arr[n]+sum[n-1];
                }
                max=Math.max(max,find(sum,k,0,sum.length-1));
            }
        }
        return max;
    }
    int find(int[] sum,int k,int l,int r){
        if(l>r) return Integer.MIN_VALUE;
        if(l==r){
            if(sum[l]<=k) return sum[l];
            return Integer.MIN_VALUE;
        }
        int m=(l+r)/2;
        int c1=find(sum,k,l,m);
        int c2=find(sum,k,m+1,r);
        for(int i=l,j=m+1;i<=m&&j<=r;){//双指针
            if(sum[j]-sum[i]<=k){
                c1=Math.max(c1,sum[j]-sum[i]);
                j++;
            }else{
                i++;
            }
        }
        //归并
        int[] a1=new int[m-l+1];
        int[] a2=new int[r-m];
        for(int i=l;i<=m;i++) a1[i-l]=sum[i];
        for(int i=m+1;i<=r;i++) a2[i-m-1]=sum[i];
        for(int i=l,j=0,n=0;i<=r;i++){
            if(n>=a2.length||(j<a1.length&&a1[j]<a2[n])){
                sum[i]=a1[j++];
            }else{
                sum[i]=a2[n++];
            }
        }
        return Math.max(c1,c2);
    }
}

前缀和+BST(用到了jdk中的BST)

class Solution {
    public int maxSumSubmatrix(int[][] m, int k) {
        int max=Integer.MIN_VALUE;
        for(int i=0;i<m[0].length;i++){
            int[] arr=new int[m.length];
            for(int j=i;j<m[0].length;j++){
                for(int n=0;n<m.length;n++){
                    arr[n]+=m[n][j];
                }
                int[] sum=new int[m.length];
                TreeSet<Integer> tree=new TreeSet<>();
                tree.add(0);
                for(int n=0;n<m.length;n++){
                    if(n==0) sum[0]=arr[0];
                    else sum[n]=arr[n]+sum[n-1];
                    Integer t=tree.ceiling(sum[n]-k);
                    if(t!=null){
                        max=Math.max(max,sum[n]-t);
                    }
                    tree.add(sum[n]);
                }
            }
        }
        return max;
    }
}

猜你喜欢

转载自blog.csdn.net/yaoct/article/details/85316422