|
| 1 | +use std::cmp::max; |
| 2 | +impl Solution { |
| 3 | + pub fn maximal_rectangle(matrix: Vec<Vec<char>>) -> i32 { |
| 4 | + let mut histagram = vec![0; matrix.get(0).unwrap().len()]; |
| 5 | + let mut ret = 0; |
| 6 | + |
| 7 | + for (i, row) in matrix.iter().enumerate() { |
| 8 | + // build histagram that begin from the first row and end at this row. |
| 9 | + for (j, v) in row.iter().enumerate() { |
| 10 | + if *v == '0' { |
| 11 | + histagram[j] = 0; |
| 12 | + } else { |
| 13 | + histagram[j] += 1; |
| 14 | + } |
| 15 | + } |
| 16 | + ret = max(ret, Self::get_area(&matrix, &mut histagram)); |
| 17 | + } |
| 18 | + ret |
| 19 | + } |
| 20 | + fn get_area(matrix: &Vec<Vec<char>>, hist: &mut Vec<i32>) -> i32 { |
| 21 | + // monotonic stack with the biggest top value. |
| 22 | + let mut mst: Vec<(i32, i32)> = Vec::new(); |
| 23 | + let mut ret = 0; |
| 24 | + |
| 25 | + hist.push(0); |
| 26 | + |
| 27 | + for (col, height) in hist.iter().enumerate() { |
| 28 | + while !mst.is_empty() && (mst.last().unwrap().1 > *height) { |
| 29 | + // value `height` smaller than the top, calculate the temp ans |
| 30 | + |
| 31 | + // the area is: |
| 32 | + // height = the height of the top element of the stack |
| 33 | + // width = (idx right now - 1) - the second biggest element idx. |
| 34 | + let prev = mst.last().unwrap_or(&(-1, 0)).clone(); |
| 35 | + mst.pop(); |
| 36 | + let prev_height = prev.1; |
| 37 | + let prev_width = col as i32 - mst.last().unwrap_or(&(-1, 0)).0 - 1; |
| 38 | + let tmp_area = prev_height * prev_width; |
| 39 | + ret = max(ret, tmp_area) |
| 40 | + } |
| 41 | + mst.push((col as i32, *height)); |
| 42 | + } |
| 43 | + |
| 44 | + hist.pop(); |
| 45 | + |
| 46 | + ret |
| 47 | + } |
| 48 | +} |
0 commit comments