【藍橋杯】找出邊界為1的最大子方陣
阿新 • • 發佈:2020-07-27
題目說明:
給定一個N*N的矩陣matrix,在這個矩陣裡,只有0和1的兩種值,返回邊框全是1的最大正方形的邊長長度。
示例:
1 | 1 | 1 | 1 |
1 | 0 | 1 | 0 |
1 | 1 | 1 | 1 |
0 | 1 | 0 | 1 |
輸出 :3
因為
1 | 1 | 1 | |
1 | 1 | ||
1 | 1 | 1 | |
分析:(列舉,遍歷所有可能性)
1.最大正方形,一定是從N向下遞減。這就要用迴圈(比如說5->4->3->2->1)
2.遍歷陣列,判斷以該點為頂點能否構成1為邊界的方陣。所以就設計到檢測四個邊框,也要用到迴圈。
1 public class CopyOfcase4 { 23 public static void main(String[] args) { 4 5 int arr[][] = { 6 { 1, 1, 1, 1,1 }, 7 { 1, 0, 1, 0,1 }, 8 { 1, 1, 0, 1,1 }, 9 { 1, 0, 1, 1,1 }, 10 { 1, 1, 1, 1,1 }, 11 }; 12 System.out.println(max(arr, arr.length));13 14 } 15 16 static int max(int[][] matrix, int N) { 17 18 int n = N;// 因為N變化,所以賦值給變數 19 while (n > 0) {// 5->4->3->2->1 20 for (int i = 0; i < N; i++) { 21 if (i + n > N) 22 break;// 如果行超過N最大邊界就要退出 23 l3: for(int j = 0; j < N; j++) { 24 if (j + n > N) 25 break;// 如果列超過N最大邊界就要退出 26 int r = i, c = j; 27 // 檢測四條邊是否都為1; 28 while (c < j+n) {// 上邊,行不變,列增加 29 // 如果改頂點為0,一定構不成全為1的邊,繼續該行下一點的判斷 30 if (matrix[r][c++] == 0) 31 continue l3; 32 } 33 // 當退出while迴圈時,c已經超陣列邊界,所以要恢復 34 c--; 35 while (r < i+n) {// 右邊,列不變,行增加 36 if (matrix[r++][c] == 0) 37 continue l3; 38 } 39 r--; 40 while (c >= j) {// 下邊,行不變,列遞減 41 if (matrix[r][c--] == 0) 42 continue l3; 43 } 44 c++; 45 while (r >= i) {// 左邊,列不變,行遞增 46 if (matrix[r--][c] == 0) 47 continue l3; 48 } 49 return n; 50 } 51 } 52 n--; 53 54 } 55 return 0; 56 } 57 }
上述程式碼輸出 5。
下一篇將退出優化程式碼,因為現在的時間複雜度是N*N*N*N,只有最後一個N可以優化,檢測四條邊的while可不可以換成常數階?
如有錯誤,望各位園友批評指正,大家一起進步呀。