邊界都是1的最大正方形大小
邊界都是1的最大正方形大小
題目描述
給定一個 N × N N \times N N×N的矩陣matrix,在這個矩陣中,只有0和1兩種值,返回邊框全是1的最大正方形的邊長長度、
例如
0 1 1 1 1
0 1 0 0 1
0 1 0 0 1
0 1 1 1 1
0 1 0 1 1
其中,邊框全是1的最大正方形的大小為 4 × 4 4 \times 4 4×4,所以返回4
[要求]
時間複雜度為 O ( n 3 ) O(n^3) O(n3),空間複雜度為 O ( n 2 ) O(n^2) O(n2)
輸入描述:
第一行一個整數N。表示矩陣的長寬。
接下來N行,每行N個整數表示矩陣內的元素
輸出描述:
輸出一個整數表示答案
示例1
輸入
5
0 1 1 1 1
0 1 0 0 1
0 1 0 0 1
0 1 1 1 1
0 1 0 1 1
輸出
4
備註:
1
⩽
N
⩽
200
1 \leqslant N \leqslant 200
1⩽N⩽200
m
a
t
r
i
x
i
,
j
=
0
/
1
matrix_{i,j} = 0/1
matrixi,j=0/1
題解:
常規解法:列舉長度,分別列舉位置,然後判斷邊界是否滿足,時間複雜度: O ( n 4 ) O(n^4) O(n4),那麼如何優化呢?
仔細思考,列舉長度和列舉位置是省不掉的,我們可以優化判斷邊界是否滿足,不用做四次迴圈挨個判斷。
具體有兩種優化方法,都是用到字首和思想:
優化一(一個額外陣列):
使用二維陣列儲存字首和。核心思想:假設從左往右列舉,當前長度為 k ,位置為 (i, j) ,那麼求邊界上的 1 的數量變成:sum1 - sum2 ,其中 sum1 是從 (i, j) 開始,長度為 k 的子陣列和,sum2 是比 sum1 小一層的子陣列和,即從 (i+1, j+1) 開始,長度為 k-2 的子陣列和,若 sum1 - sum2 == 4*k - 4,則是一個邊界為 1 的子陣列,在所有合法的情況中找最大值即可。
優化一程式碼:
#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 201;
int a[N][N];
int n;
int main(void) {
scanf("%d", &n);
int ret = 0;
for ( int i = 1; i <= n; ++i ) {
for ( int j = 1; j <= n; ++j ) {
scanf("%d", &a[i][j]);
if ( a[i][j] && !ret ) ret = 1;
a[i][j] += a[i - 1][j] + a[i][j - 1] - a[i - 1][j - 1];
}
}
int x, y;
for ( int k = 2; k <= n; ++k ) {
for ( int i = 1; i + k - 1 <= n; ++i ) {
for ( int j = 1; j + k - 1 <= n; ++j ) {
x = i + k - 1;
y = j + k - 1;
int sum1 = a[x][y] + a[i - 1][j - 1];
sum1 -= (a[x][j - 1] + a[i - 1][y]);
if ( k == 2 && sum1 == 4 ) {
ret = max( ret, 2 );
continue;
}
if ( k > 2 ) {
int sum2 = a[x - 1][y - 1] + a[i][j];
sum2 -= ( a[x - 1][j] + a[i][y - 1] );
if ( sum1 - sum2 == 4 * k - 4 ) ret = max( ret, k );
}
}
}
}
return 0 * printf("%d\n", ret);
}
優化二(兩個額外陣列):
使用兩個額外陣列,記錄每個位置往上最長多少個連續的1,往左最長多少個連續的1。在判斷邊界是否滿足條件時,直接通過預處理陣列判斷即可。
優化二程式碼:
#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 200;
int n, val;
int r[N][N];
int c[N][N];
int main(void) {
scanf("%d", &n);
for ( int i = 0; i < n; ++i ) {
for ( int j = 0; j < n; ++ j) {
scanf("%d", &val);
if ( !val ) continue;
r[i][j] = !j ? 1 : r[i][j - 1] + 1;
c[i][j] = !i ? 1 : c[i - 1][j] + 1;
}
}
int tmp, ret = 0;
for ( int i = n - 1; i >= 0; --i ) {
for ( int j = n - 1; j >= 0; --j ) {
tmp = min( r[i][j], c[i][j] );
while ( tmp > ret ) {
if ( r[i - tmp + 1][j] >= tmp && c[i][j - tmp + 1] >= tmp ) {
ret = tmp;
break;
}
--tmp;
}
}
}
return 0 * printf("%d\n", ret);
}
法一空間小點,法二時間小點,自己選吧2333。。。
相關文章
- 1139. 最大的以 1 為邊界的正方形
- 【DP】最大正方形
- css實現最大正方形CSS
- 第四章:多維陣列和矩陣 ------------- 4.4 找出邊界為1的最大子方陣陣列矩陣
- cad游標大小怎麼調 cad游標中心正方形大小設定
- 《超越邊界》
- 二分查詢左邊界,右邊界,>=,>,<=,<
- LeetCode: 221_Maximal Square | 二維0-1矩陣中計算包含1的最大正方形的面積 | MediumLeetCode矩陣
- 穿越邊界的姿勢
- [LeetCode 中等 動態規劃 ]221. 最大正方形LeetCode動態規劃
- 【AutoCAD .NET】如何在無邊界Hatch上選擇邊界點?
- 關於運營邊界的思考
- 【二分】【邊界判定】
- AUTOCAD——快速提取邊界線
- 絕對值邊界法
- React 錯誤邊界元件React元件
- 寫網路爬蟲的法律邊界爬蟲
- 無邊界網路的劃分建立
- 陣列左邊減去右邊數值的最大差值陣列
- 邊界佈局管理器
- Python修改柱狀圖邊緣柱子與圖邊界的距離Python
- 劃分微服務邊界的5個特徵微服務特徵
- 《每週一點canvas動畫》——邊界檢測與摩擦力(1)Canvas動畫
- 在平時開發的時候,你有考慮過邊界問題嗎?說說你對邊界的理解!
- 如何築造資料安全邊界
- Pytorch 四種邊界填充方式(Padding)PyTorchpadding
- 說說你對自我認識邊界的理解
- 突破邊界,華為儲存的破壁之旅
- 衝破邊界:遊戲為現實的切片遊戲
- 學生,B站的邊界與天花板
- 使用Dice loss實現清晰的邊界檢測
- 打破邊界,邊緣計算有何應用場景?
- 更改 Sublime text 3 側邊欄字型大小
- 視覺化學習:利用向量判斷多邊形邊界視覺化
- 借AI之勢,打破創意與想象的邊界AI
- FortiGate NGFW打造安全、高效、智慧的邊界安全樞紐
- 直播遊戲的合理使用與侵權邊界在哪?遊戲
- 邦盛科技王雷:AI風控的「能力邊界」AI