矩陣中求子矩形

2021-07-02 22:34:46 字數 3506 閱讀 9992

有乙個n * n的矩形,其中每個元素只可能是0or1。比如如下矩陣a:

1 1 0 0

0 0 1 1

1 0 1 0

1 1 0 1

其中a[0][0], a[0][1], a[3][0], a[3][1]這四個元素恰好是乙個長方形的四個角,且每個元素都是1. 因此稱這四個元素圍成了乙個子矩形。

現在需要判斷,給定的矩陣a中,判斷是否存在這樣四個元素,都是1,且恰好圍成乙個子矩形?

暴力法顯然,只需要列舉 top-left,還有 bottom-right 就可以確定出這四個元素了。top-left [i1, j1], bottom-right [i2, j2]。偽**如下:

for

i1<- 0 to

n-1for

j1<- 0 to

n-1for

i2<-

i1 + 1 to

n-1for

j2<-

j2 + 1 to

n-1check_are_all_one(a

[i1]

[j1], a

[i1]

[j2], a

[i2]

[j1], a

[i2]

[j2])

t(n) = o(n^4)

改進方案1

可以只需要列舉j1, j2, 然後 i 從 0 ~ n-1 掃瞄一遍就行。

for j1 <-0to

n-1for

j2<-

j1+1

ton-1

one_pair_count

<-

0for

i<-0to

n-1if

a[i][j1] & a[i][j2] then

one_pair_count

<-

one_pair_count + 1

ifone_pair_count >

= 2 then // 只需要出現過兩次a[i][j1], a[i][j2]都是1,就可以由他們圍成乙個矩形

return true

return false

時間複雜度為 t(n) = o(n^3)

改進方案2

這個方案可以將複雜度改進為 o(n^2),但是需要引入輔助空間,mark[n][n]

a矩陣:

1 1 0 0

0 0 1 1

1 0 1 0

1 1 0 1

從a的第一行開始往下掃,

row 1:1 1 0 0

這裡意味著第一列(column 1,簡稱c1) 和第二列(column 2,簡稱c2)可以構成乙個待求矩形的上邊。對應的mark表為:

c1  c2  c3  c4

c1 0 1 0 0

c2 1 0 0 0

c3 0 0 0 0

c4 0 0 0 0

如果row1 是:1 1 0 1,那麼意味著 c1 和 c2,c2 和 c3,c1 和 c3都可以構成矩形的上邊。此時對應的mark表為:

c1  c2  c3  c4

c1 0 1 0 1

c2 1 0 0 1

c3 0 0 0 0

c4 1 1 0 0

掃瞄第二行,row2:0 0 1 1,c3, c4為1,更新mark[3-1][4-1]=1, mark[4-1][3-1]=1

mark表更新為:

c1  c2  c3  c4

c1 0 1 0 0

c2 1 0 0 0

c3 0 0 0 1

c4 0 0 1 0

掃瞄第三行:row3:1 0 1 0, c1,c3為1,更新mark[1-1][3-1]=1, mark[3-1][1-1]=1

mark表更新為:

c1  c2  c3  c4

c1 0 1 1 0

c2 1 0 0 0

c3 1 0 0 1

c4 0 0 1 0

掃瞄第四行,row4:1 1 0 1,c1,c2,c4為1,更新mark[1-1][2-1]=1, mark[2-1][1-1]=1, mark[1-1][4-1]=1, mark[4-1][1-1]=1, mark[2-1][4-1]=1, mark[4-1][2-1]=1

mark表更新為

c1  c2  c3  c4

c1 0 2 0 1

c2 2 0 0 1

c3 0 0 0 0

c4 1 1 0 0

此時發現mark[0][1] = 2,即意味著第一列和第二列有兩次掃瞄中,都匹配上了,這樣的話,選擇第一列和第二列作為矩形的左右列即可,然後從上往下掃一次(o(n)時間),即可求得矩形上下邊界

總的時間複雜度分析:

**如下:

#include 

#include

#include

#include

using

namespace

std;

class solution ,,,

};vector

> matrix;

for (int i = 0; i < 4; i++)

cout

<< "check: "

<< checkhasrectangle(matrix) << endl;

}bool checkhasrectangle(vector

> &matrix)

}// cout

printf("four elements: (%d,%d), (%d,%d), (%d,%d), (%d,%d)\n",

target_r1, target_c1, target_r1, target_c2,

target_r2, target_c1, target_r2, target_c2);

return

true;}}

}}

return

false;

}};int main()

LA3029 矩陣中求子矩陣最大問題

la3029 題意給你乙個矩陣,每個單元格要麼為空,要麼為滿,求全是空的最大子矩陣的格仔數 3.最樸素的演算法是列舉所有的子矩陣的左上角的點和右下角的點,這樣就能確定乙個矩形,然後再遍歷這個矩陣,看矩陣是否全是空。複雜度大概是o m 2 n 2 通過掃瞄法,每次維護left i j right i ...

CDQ求子矩陣的和

description 維護乙個w w的矩陣,初始值均為s.每次操作可以增加某格仔的權值,或詢問某子矩陣的總權值.修改運算元m 160000,詢問數q 10000,w 2000000.input 第一行兩個整數,s,w 其中s為矩陣初始值 w為矩陣大小 接下來每行為一下三種輸入之一 不包含引號 1 ...

OfferX 矩形和矩陣

題目 48.rotate image 將乙個矩形順時針翻轉90 解 先將矩形按行翻轉,然後進行mirror操作 class solution public void reverse int matrix public void mirrorrotate int matrix public void ...