Skip to content

Commit 034c55b

Browse files
authored
Create SubMatrixSum.java
1 parent f097166 commit 034c55b

1 file changed

Lines changed: 201 additions & 0 deletions

File tree

DanDiaoStack/SubMatrixSum.java

Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
import java.util.*;
2+
3+
public class SubMatrixSum{
4+
5+
private int[][] arr;
6+
private int[][] compress;
7+
8+
public SubMatrixSum(int[][] _arr){
9+
arr = _arr;
10+
getCompress();
11+
}
12+
13+
private void getCompress(){
14+
int N=arr.length;
15+
int M = arr[0].length;
16+
compress = new int[N][M];
17+
18+
for (int i=0; i<M; i++) {
19+
compress[0][i] = arr[0][i];
20+
}
21+
22+
for (int i=1; i<N; i++) {
23+
//System.out.println();
24+
for (int j=0; j<M;j++ ) {
25+
compress[i][j] = (arr[i][j] == 0 ? 0: compress[i-1][j] + 1);
26+
//System.out.print(compress[i][j]+",");
27+
}
28+
}
29+
}
30+
31+
public int getSubResult(int[] temp){
32+
33+
int[][] result=getArray(temp);
34+
int sum = 0;
35+
36+
// for (int i=0; i<result.length;i++ ) {
37+
// for (int j=0; j<result[i].length; j++) {
38+
// System.out.print(result[i][j]+",");
39+
// }
40+
// System.out.println();
41+
// }
42+
43+
for (int i=0; i<result.length;i++ ) {
44+
if(result[i][1]==result[i][0]&&result[i][0]==0) continue;
45+
int size = (result[i][1]==-1 ? temp.length : result[i][1]) - result[i][0];
46+
int low = Math.max(result[i][0]==-1?0:temp[result[i][0]],result[i][1]==-1?0:temp[result[i][1]]);
47+
int high = temp[i];
48+
49+
sum+=getNum(low,high,size-1);
50+
51+
}
52+
return sum;
53+
}
54+
55+
56+
public int getResult(){
57+
int sum = 0;
58+
59+
for (int i=0; i<compress.length;i++ ) {
60+
sum+= getSubResult(compress[i]);
61+
}
62+
return sum;
63+
}
64+
65+
66+
67+
private int[][] getArray(int[] temp){
68+
Stack<Integer> stack = new Stack<Integer> ();
69+
int[][] result = new int[temp.length][2];
70+
for (int i=0; i<temp.length; i++) {
71+
if(stack.isEmpty()){
72+
stack.push(i);
73+
}else{
74+
while(!stack.isEmpty()){
75+
if(temp[stack.peek()] < temp[i]){
76+
break;
77+
}
78+
int cur = stack.pop();
79+
if(temp[cur] != temp[i]){
80+
result[cur][0]= stack.isEmpty()?-1:stack.peek();
81+
result[cur][1]= i;
82+
}
83+
}
84+
stack.push(i);
85+
}
86+
}
87+
while(!stack.isEmpty()){
88+
int cur = stack.pop();
89+
result[cur][0]= stack.isEmpty()?-1:stack.peek();
90+
result[cur][1]= -1;
91+
}
92+
93+
return result;
94+
}
95+
96+
private int getNum(int start,int end,int length){
97+
//System.out.println("start="+start+",end="+end+",length="+length);
98+
return (length*(length+1)/2) * (end-start);
99+
}
100+
101+
public static void main(String[] args){
102+
int[][] arr = new int[][]{
103+
{1,1,0,1,1,0,1,1,0,1,1},
104+
{1,1,0,1,1,1,1,1,0,1,1},
105+
{0,1,1,1,1,1,1,1,1,1,0},
106+
{1,1,0,1,1,1,1,1,1,1,1},
107+
{1,1,0,1,1,0,1,1,1,0,1},
108+
};
109+
SubMatrixSum ss = new SubMatrixSum(arr);
110+
System.out.println("Sum = "+ss.getResult());
111+
System.out.println("Sum = "+numSubmat(arr));
112+
}
113+
114+
115+
116+
117+
118+
119+
120+
121+
122+
123+
124+
125+
126+
127+
128+
129+
130+
131+
132+
133+
134+
135+
136+
137+
138+
139+
140+
141+
142+
143+
144+
145+
146+
147+
148+
149+
150+
151+
public static int numSubmat(int[][] mat) {
152+
if (mat == null || mat.length == 0 || mat[0].length == 0) {
153+
return 0;
154+
}
155+
int nums = 0;
156+
int[] height = new int[mat[0].length];
157+
for (int i = 0; i < mat.length; i++) {
158+
for (int j = 0; j < mat[0].length; j++) {
159+
height[j] = mat[i][j] == 0 ? 0 : height[j] + 1;
160+
}
161+
nums += countFromBottom(height);
162+
}
163+
return nums;
164+
165+
}
166+
167+
public static int countFromBottom(int[] height) {
168+
if (height == null || height.length == 0) {
169+
return 0;
170+
}
171+
int nums = 0;
172+
int[] stack = new int[height.length];
173+
int si = -1;
174+
for (int i = 0; i < height.length; i++) {
175+
while (si != -1 && height[stack[si]] >= height[i]) {
176+
int cur = stack[si--];
177+
if (height[cur] > height[i]) {
178+
int left = si == -1 ? -1 : stack[si];
179+
int n = i - left - 1;
180+
int down = Math.max(left == -1 ? 0 : height[left], height[i]);
181+
nums += (height[cur] - down) * num(n);
182+
}
183+
184+
}
185+
stack[++si] = i;
186+
}
187+
while (si != -1) {
188+
int cur = stack[si--];
189+
int left = si == -1 ? -1 : stack[si];
190+
int n = height.length - left - 1;
191+
int down = left == -1 ? 0 : height[left];
192+
nums += (height[cur] - down) * num(n);
193+
}
194+
return nums;
195+
}
196+
197+
public static int num(int n) {
198+
return ((n * (1 + n)) >> 1);
199+
}
200+
201+
}

0 commit comments

Comments
 (0)