【問題描述】[第221題][最大正方形][中等]
在一個由 0 和 1 組成的二維矩陣內,找到只包含 1 的最大/長方形正方形,并返回其面積。示例:輸入: 1 0 1 0 0
1 0 1 1 1
1 1 1 1 1
1 0 0 1 0
長方形 輸出: 6
正方形 輸出: 4
【解答思路】
1. 長方形 暴力
時間復雜度:O(N^2) 空間復雜度:O(N^2)
public int maximalRectangle(char[][] matrix
) {if (matrix
.length
== 0) {return 0;}int[][] width
= new int[matrix
.length
][matrix
[0].length
];int maxArea
= 0;for (int row
= 0; row
< matrix
.length
; row
++) {for (int col
= 0; col
< matrix
[0].length
; col
++) {if (matrix
[row
][col
] == '1') {if (col
== 0) {width
[row
][col
] = 1;} else {width
[row
][col
] = width
[row
][col
- 1] + 1;}} else {width
[row
][col
] = 0;}int minWidth
= width
[row
][col
];for (int up_row
= row
; up_row
>= 0; up_row
--) {int height
= row
- up_row
+ 1;minWidth
= Math
.min(minWidth
, width
[up_row
][col
]);maxArea
= Math
.max(maxArea
, height
* minWidth
);}}}return maxArea
;
}
2. 正方形 暴力
- 正方形的面積是邊長乘邊長, maxArea 是沒有意義的-- 只記錄最大邊長即可。然后是其它細節的修改,讓代碼更簡潔,代碼如下。
時間復雜度:O(N^2) 空間復雜度:O(N^2)
public int maximalSquare(char[][] matrix
) {if (matrix
.length
== 0) {return 0;}int[][] width
= new int[matrix
.length
][matrix
[0].length
];int maxSide
= 0;for (int row
= 0; row
< matrix
.length
; row
++) {for (int col
= 0; col
< matrix
[0].length
; col
++) {if (matrix
[row
][col
] == '1') {if (col
== 0) {width
[row
][col
] = 1;} else {width
[row
][col
] = width
[row
][col
- 1] + 1;}} else {width
[row
][col
] = 0;}int curWidth
= width
[row
][col
];for (int up_row
= row
; up_row
>= 0; up_row
--) {int height
= row
- up_row
+ 1;if (width
[up_row
][col
] <= maxSide
|| height
> curWidth
) {break;}maxSide
= Math
.max(height
, maxSide
);}}}return maxSide
* maxSide
;
}
2. 正方形 動態規劃
第 1 步:設計狀態
dp[i][j] 表示以 matrix[i][j] 為右下角正方形的最大邊長
第 2 步:狀態轉移方程
dp[i][j] = Min(dp[i-1][j],dp[i][j-1],dp[i-1][j-1]) + 1
當前點的左邊,上邊,左上角的三個點中選一個最小值,然后加 1
第 3 步:考慮初始化
第一行和第一列的 dp[i][j] = matrix[i][j] - ‘0’,也就意味著 dp[i][j] 要么是 0 要么是 1
第 4 步:考慮輸出
第 5 步:考慮是否可以狀態壓縮
時間復雜度:O(N^2) 空間復雜度:O(N)
public int maximalSquare(char[][] matrix
) {int rows
= matrix
.length
;if (rows
== 0) {return 0;}int cols
= matrix
[0].length
;int[][] dp
= new int[rows
+ 1][cols
+ 1];int maxSide
= 0;for (int i
= 1; i
<= rows
; i
++) {for (int j
= 1; j
<= cols
; j
++) {if (matrix
[i
- 1][j
- 1] == '0') {dp
[i
][j
] = 0;} else {dp
[i
][j
] = Math
.min(dp
[i
- 1][j
], Math
.min(dp
[i
][j
- 1], dp
[i
- 1][j
- 1])) + 1;maxSide
= Math
.max(dp
[i
][j
], maxSide
);}}}return maxSide
* maxSide
;
}
【總結】
1.動態規劃流程
第 1 步:設計狀態
第 2 步:狀態轉移方程
第 3 步:考慮初始化
第 4 步:考慮輸出
第 5 步:考慮是否可以狀態壓縮
- 二維數組 -> 一維數組
2. 行 row 列 col 注意邊界!
int rows = matrix.length;
nt cols = matrix[0].length;
3. 暴力 ->優化
轉載鏈接:https://leetcode-cn.com/problems/maximal-square/solution/xiang-xi-tong-su-de-si-lu-fen-xi-duo-jie-fa-by–46/
參考鏈接:https://leetcode-cn.com/problems/maximal-square/solution/li-jie-san-zhe-qu-zui-xiao-1-by-lzhlyle/
總結
以上是生活随笔為你收集整理的[Leedcode][JAVA][第85题][第221题][最大正方形][动态规划]的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。