49
49
*
50
50
*/
51
51
52
+ // BETTER DYNAMIC PROGRAMMING
53
+ // TIME: O(mn)
54
+ // SPACE: O(n)
55
+ // --------------------------
52
56
class Solution {
53
57
public int maximalSquare (char [][] matrix ) {
54
- int maxRow = matrix .length , maxCol = maxRow > 0 ? matrix [0 ].length : 0 ;
55
- int maxSqrLen = 0 ;
56
- for (int row = 0 ; row < maxRow ; row ++) {
57
- for (int col = 0 ; col < maxCol ; col ++) {
58
+ int maxRow = matrix .length ;
59
+ int maxCol = maxRow > 0 ? matrix [0 ].length : 0 ;
58
60
59
- // Check for the maximum square size relative to current element
60
- // 1 - > ?
61
- // |
62
- // v
63
- // ?
64
- // Searching from left to right and top to bottom
65
- if (matrix [row ][col ] == '1' ) {
66
- int sqrLen = 1 ;
67
- boolean isExpandSquare = true ;
61
+ // Instead of alternate matrix, we use an array instead since we only need
62
+ // to know the top left element from the current (which is the top row) per
63
+ // row iteration
64
+ int [] dp = new int [maxCol + 1 ];
65
+ int maxSqrLen = 0 , prev = 0 ;
68
66
69
- // If square is expandable or not at the lower edge and/or right edge
70
- // of the matrix
71
- while (sqrLen + row < maxRow && sqrLen + col < maxCol && isExpandSquare ) {
67
+ // Start loop from the top left of the matrix
68
+ for (int row = 1 ; row <= maxRow ; row ++) {
69
+ for (int col = 1 ; col <= maxCol ; col ++) {
70
+ int next = dp [col ];
71
+ // pre
72
+ // v
73
+ // S [ 0 , 0 , 0 , 0 , 0 ]
74
+ // ^ ^
75
+ // c-1 nxt
76
+ //
77
+ if (matrix [row - 1 ][col - 1 ] == '1' ) {
78
+ dp [col ] = Math .min (Math .min (dp [col - 1 ], prev ), next ) + 1 ;
72
79
73
- // Look for zero horizontally for expansion
74
- for (int i = col ; i <= sqrLen + col ; i ++) {
75
- if (matrix [row + sqrLen ][i ] == '0' ) {
76
- isExpandSquare = false ;
77
- break ;
78
- }
79
- }
80
-
81
- // Look for zero vertically for expansion
82
- for (int i = row ; i <= sqrLen + row ; i ++) {
83
- if (matrix [i ][col + sqrLen ] == '0' ) {
84
- isExpandSquare = false ;
85
- break ;
86
- }
87
- }
88
-
89
- if (isExpandSquare )
90
- sqrLen ++;
91
- }
92
-
93
- if (maxSqrLen < sqrLen ) {
94
- maxSqrLen = sqrLen ;
95
- }
80
+ maxSqrLen = Math .max (maxSqrLen , dp [col ]);
81
+ } else {
82
+ dp [col ] = 0 ;
96
83
}
84
+ prev = next ;
97
85
}
98
86
}
99
87
return maxSqrLen * maxSqrLen ;
@@ -102,71 +90,94 @@ public int maximalSquare(char[][] matrix) {
102
90
103
91
104
92
93
+ // DYNAMIC PROGRAMMING
94
+ // TIME: O(mn)
95
+ // SPACE: O(mn)
96
+ // -------------------
105
97
// class Solution {
106
98
// public int maximalSquare(char[][] matrix) {
107
- // // Check if matrix is empty
108
- // if (matrix == null || matrix.length == 0 || matrix[0].length == 0) return 0;
109
- // // Notes:
110
- // // 1's ands 0's are in Char format?
111
- //
112
- // // [["1","0","1","0","0"]
113
- // // ["1","0","1","1","1"]
114
- // // ["1","1","1","1","1"]
115
- // // ["1","0","0","1","0"]]
116
- // //
117
- // // [["1","0","1","0","0"],["1","0","1","1","1"],["1","1","1","1","1"],["1","0","0","1","0"]]
118
- //
119
- // // Approach:
120
- // // BRUTE FORCE:
121
- // // Loop over matrix m x n
122
- // // Check bottom row and right column for 1's
123
- // // Create a function for checking for surrounding 1's and 0's
124
- // // if (all 1's)
125
- // // updateArea;
126
- // // if (bottom row || right col nomore)
127
- // // break
128
- //
129
- // // Right and bottom search
99
+ // int maxRow = matrix.length;
100
+ // int maxCol = maxRow > 0 ? matrix[0].length : 0;
101
+ // // dp = separate matrix for mapping dynamic programming values
102
+ // // +1 row and col for padding
103
+ // int[][] dp = new int[maxRow + 1][maxCol + 1];
104
+ // int maxSqrLen = 0;
105
+ // // Start loop from the top left of the matrix down to the bottom right
106
+ // // Starting from the second row and col, hence the padding
107
+ // for (int row = 1; row <= maxRow; row++) {
108
+ // for (int col = 1; col <= maxCol; col++) {
109
+ // // The the current element in matrix if 1
110
+ // if (matrix[row - 1][col - 1] == '1'){
111
+ // // dp values will eventually be filled up as the loop progresses, so
112
+ // // initially, the top and/or left of current dp matrix point will be
113
+ // // the default value of initialized int array, that is 0
114
+ // int topLeft = dp[row - 1][col - 1];
115
+ // int top = dp[row - 1][col];
116
+ // int left = dp[row][col - 1];
117
+ // dp[row][col] = Math.min(Math.min(left, top), topLeft) + 1;
118
+ // maxSqrLen = Math.max(maxSqrLen, dp[row][col]);
119
+ // }
120
+ // }
121
+ // }
122
+ // return maxSqrLen * maxSqrLen;
123
+ // }
124
+ // }
125
+
126
+
127
+
128
+ // BRUTE FORCE SOLUTION
129
+ // TIME: O((mn)^2)
130
+ // SPACE: O(1)
131
+ // --------------------
132
+ // class Solution {
133
+ // public int maximalSquare(char[][] matrix) {
134
+ // int maxRow = matrix.length, maxCol = maxRow > 0 ? matrix[0].length : 0;
135
+ // int maxSqrLen = 0;
136
+ // for (int row = 0; row < maxRow; row++) {
137
+ // for (int col = 0; col < maxCol; col++) {
130
138
//
131
- // // First check if current index is 1, otherwise return 0
132
- // // Check if next nth binary is 1, if so, check the next nth, while recording
133
- // // how far it went so far. (this will be used how far to search mth wise or
134
- // // vertically)
135
- // // When it horizontal search reaches the closest zero break and go to the
136
- // // next mth and repeat certain times the furthest horizontal search reached
139
+ // // Check for the maximum square size relative to current element
140
+ // // 1 - > ?
141
+ // // |
142
+ // // v
143
+ // // ?
144
+ // // Searching from left to right and top to bottom
145
+ // if (matrix[row][col] == '1') {
146
+ // int sqrLen = 1;
147
+ // boolean isExpandSquare = true;
137
148
//
138
- // // at the end, get the minimum value of the horizontal searches to get the
139
- // // biggest area of the matrix at the given start location
149
+ // // If square is expandable or not at the lower edge and/or right edge
150
+ // // of the matrix
151
+ // while (sqrLen + row < maxRow && sqrLen + col < maxCol && isExpandSquare) {
140
152
//
141
- // int rowMax = matrix.length;
142
- // int colMax = matrix[0].length;
143
- // int maxSquareSide = 0;
144
- // for (int row = 0; row < rowMax - 1; row++) { // Exclude last row and col
145
- // for (int col = 0; col < colMax - 1; col++) {
153
+ // // Look for zero horizontally for expansion
154
+ // for (int i = col; i <= sqrLen + col; i++) {
155
+ // if (matrix[row + sqrLen][i] == '0') {
156
+ // isExpandSquare = false;
157
+ // break;
158
+ // }
159
+ // }
146
160
//
147
- // // find furthest non 0 from the right
148
- // int furthestNonZeroSubCol = findFurthestNonZeroSubCol(matrix, row, col, colMax);
149
- // maxSquareSide = Math.max(maxSquareSide,
150
- // evaluateOneSquare(matrix, row, col, furthestNonZeroSubCol));
161
+ // // Look for zero vertically for expansion
162
+ // for (int i = row; i <= sqrLen + row; i++) {
163
+ // if (matrix[i][col + sqrLen] == '0') {
164
+ // isExpandSquare = false;
165
+ // break;
166
+ // }
167
+ // }
151
168
//
152
- // }
153
- // }
154
- // }
169
+ // if (isExpandSquare)
170
+ // sqrLen++;
171
+ // }
155
172
//
156
- // public int findFurthestNonZeroSubCol(char[][] matrix, int row, int col, int colMax) {
157
- // int furthestNonZeroSubCol = 0;
158
- // for (int i = col; i < colMax; i++) {
159
- // if (matrix[row][i] == '0') break;
160
- // else furthestNonZeroSubCol++;
173
+ // // Record sqrLen if bigger than current
174
+ // if (maxSqrLen < sqrLen) {
175
+ // maxSqrLen = sqrLen;
176
+ // }
177
+ // }
161
178
// }
162
- // return furthestNonZeroSubCol;
163
- // }
164
- //
165
- // public int evaluateOneSquare(char[][] matrix, int row, int col, int size) {
166
- // while (++row <= size) {
167
- // int furthestNonZeroSubCol = findFurthestNonZeroSubCol(matrix, row, col, size);
168
- // if (furthestNonZeroSubCol <= size)
169
- // continue;
170
179
// }
180
+ // return maxSqrLen * maxSqrLen;
171
181
// }
172
182
// }
183
+
0 commit comments