leetcode 363. Max Sum of Rectangle No Larger Than K
阿新 • • 發佈:2018-12-30
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?
轉化成字首和歸併排序+雙指標查詢字首和之差接近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; } }