- Notifications
You must be signed in to change notification settings - Fork 40
/
Copy pathMaximumSumRectangularSubMatrix.java
104 lines (81 loc) · 3.36 KB
/
MaximumSumRectangularSubMatrix.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
/*
https://youtu.be/yCQN096CwWM
https://github.com/mission-peace/interview/blob/master/src/com/interview/dynamic/SubRectangularMatrixWithMaximumSum.java
We Use Kadane's Algorithm to solve this problem
*/
classMaxSumRectangularSubMatrix{
classResult{
intmaxSum;
intleftBound;
intrightBound;
intlowBound;
intupBound;
}
classKadaneResult{
intsum;
intstart; //will indicate the start row of the max sum sub matrix
intend; //will indicate the end row of the max sum sub matrix
}
publicResultmaxSum(intA[][]){
introws = A.length;
intcols = A[0].length;
intkadaneCol[] = newint[rows];
Resultresult = newResult();
//we set a new start boundary for the sub-matrix --> this is the left boundary
for(intleft=0 ; left < cols ; left++){
//Clear the previous values
Arrays.fill(kadaneCol,0); //O(n)
//the left boundary is set, but we move the right boundary towards the end of the matrix
for(intright=left ; right < cols ; right++){
//add values from the newly shifted right boundary
//This is done because we are applying Kadane's Algorithm which works on 1D arrays
//We pass an array(to the kadane's algorithm) containing cummulative sum of each row(which makes the array 1D)
//Kadane's algo finds the max sum subarray from this array --> This is nothing but the max sum sub matrix
//left and right are set in this function and Kadane's algo helps to fix the up and low.
for(inti=0;i<rows;i++){
kadaneCol[i] += A[i][right];
}
//Update the current result
KadaneResultkadaneResult = kadane(kadaneCol);
if(kadaneResult.sum > result.maxSum){
result.maxSum = kadaneResult.sum;
result.leftBound = left;
result.rightBound = right;
result.upBound = kadaneResult.start;
result.lowBound = kadaneResult.end;
}
}
}
returnresult;
}
/*
Time Complexity - O((col^2)*row) --> cubic
Space Complexity - O(row)
*/
publicKadaneResultkadane(intA[]){ //to return the maxSum, start and end in linear time
intn = A.length;
if(n == 0) return0;
KadaneResultkr = null;
intmaxEndingHere = A[0];
intmaxSoFar = A[0];
intmaxStart = 0;
intstart = 0;
intmaxEnd = 0;
for(inti=1 ; i < n ; i++){
//include current element in the sub-array sum
maxEndingHere+=A[i];
//check if starting a new sub-array gives a greater sum than the current sum
if(maxEndingHere < A[i]){
start = i;
maxEndingHere = A[i];
}
//update the overall max-sum
if(maxSoFar < maxEndingHere){
maxSoFar = maxEndingHere;
maxEnd = i;
maxStart = start;
}
}
returnnewKadaneResult(maxSoFar, maxStart, maxEnd);
}
}