2014-04-29 04:30
题目:给定一个由‘0’或者‘1’构成的二维数组,找出一个四条边全部由‘1’构成的正方形(矩形中间可以有‘0’),使得矩形面积最大。
解法:用动态规划思想,记录二维数组每个元素向上下左右四个方向各有多少个连续的‘1’,然后用O(n^3)时间计算出满足条件的最大正方形。时间复杂度O(n^3),空间复杂度O(n^2)。
代码:
1 // 18.11 Given an NxN matrix of 0s and 1s, find out a subsquare whose all four borders are all 1s. If multiple satisfies the condition, any one is OK.
2 // I‘ll return the size and the left top corner of the subsquare.
3 #include <iostream>
4 #include <vector>
5 using namespace std;
6
7 class Solution {
8 public:
9 void maxSubsquare(const vector<vector<int> > &matrix, int &max_left, int &max_top, int &max_size) {
10 int n = matrix.size();
11
12 max_left = max_top = max_size = -1;
13
14 if (n <= 1) {
15 return;
16 }
17
18 vector<vector<int> > top (n, vector<int>(n));
19 vector<vector<int> > bottom(n, vector<int>(n));
20 vector<vector<int> > left (n, vector<int>(n));
21 vector<vector<int> > right (n, vector<int>(n));
22
23 int i, j;
24 int tmp;
25
26 // use DP to preprocess the data, count how many consecutive 1s are there to the left, right, top, bottom of matrix[i][j].
27 for (i = 0; i <= n - 1; ++i) {
28 tmp = 0;
29 for (j = 0; j <= n - 1; ++j) {
30 left[i][j] = matrix[i][j] ? (++tmp) : (tmp = 0);
31 }
32 }
33 for (j = 0; j <= n - 1; ++j) {
34 tmp = 0;
35 for (i = 0; i <= n - 1; ++i) {
36 top[i][j] = matrix[i][j] ? (++tmp) : (tmp = 0);
37 }
38 }
39 for (i = n - 1; i >= 0; --i) {
40 tmp = 0;
41 for (j = n - 1; j >= 0; --j) {
42 right[i][j] = matrix[i][j] ? (++tmp) : (tmp = 0);
43 }
44 }
45 for (j = n - 1; j >= 0; --j) {
46 tmp = 0;
47 for (i = n - 1; i >= 0; --i) {
48 bottom[i][j] = matrix[i][j] ? (++tmp) : (tmp = 0);
49 }
50 }
51
52 int len;
53 // O(n ^ 3) solution with O(n ^ 2) space usage.
54 for (i = 0; i < n; ++i) {
55 for (j = 0; j < n; ++j) {
56 for (len = 2; len + i <= n && len + j <= n; ++len) {
57 if (right[i][j] < len || bottom[i][j] < len) {
58 continue;
59 }
60 if (left[i][j + len - 1] < len || bottom[i][j + len - 1] < len) {
61 continue;
62 }
63 if (right[i + len - 1][j] < len || top[i + len - 1][j] < len) {
64 continue;
65 }
66 if (left[i + len - 1][j + len - 1] < len || top[i + len - 1][j + len - 1] < len) {
67 continue;
68 }
69 // all four borders are ‘1‘s.
70 if (len > max_size) {
71 max_top = i;
72 max_left = j;
73 max_size = len;
74 }
75 }
76 }
77 }
78
79 // clear up data
80 for (i = 0; i < n; ++i) {
81 left[i].clear();
82 right[i].clear();
83 top[i].clear();
84 bottom[i].clear();
85 }
86 left.clear();
87 right.clear();
88 top.clear();
89 bottom.clear();
90 };
91 };
92
93 int main()
94 {
95 int n;
96 int i, j;
97 vector<vector<int> > matrix;
98 Solution sol;
99 int max_left, max_top, max_size;
100
101 while (cin >> n && n > 0) {
102 matrix.resize(n);
103 for (i = 0; i < n; ++i) {
104 matrix[i].resize(n);
105 }
106
107 for (i = 0; i < n; ++i) {
108 for (j = 0; j < n; ++j) {
109 cin >> matrix[i][j];
110 }
111 }
112
113 sol.maxSubsquare(matrix, max_left, max_top, max_size);
114 if (max_size > 0) {
115 cout << max_top << ‘ ‘ << max_left << endl;
116 cout << max_top << ‘ ‘ << max_left + max_size - 1 << endl;
117 cout << max_top + max_size - 1 << ‘ ‘ << max_left << endl;
118 cout << max_top + max_size - 1 << ‘ ‘ << max_left + max_size - 1 << endl;
119 } else {
120 cout << "No subsquare found." << endl;
121 }
122
123 for (i = 0; i < n; ++i) {
124 matrix[i].clear();
125 }
126 matrix.clear();
127 }
128
129 return 0;
130 }
《Cracking the Coding Interview》——第18章:难题——题目11,码迷,mamicode.com
时间: 2024-12-25 20:55:06