1.題目
給你一個 m * n 的矩陣,矩陣中的元素不是 0 就是 1,請你統計並返回其中完全由 1 組成的 正方形 子矩陣的個數。
示例 1:
輸入:matrix =
[
[0,1,1,1],
[1,1,1,1],
[0,1,1,1]
]
輸出:15
解釋:
邊長爲 1 的正方形有 10 個。
邊長爲 2 的正方形有 4 個。
邊長爲 3 的正方形有 1 個。
正方形的總數 = 10 + 4 + 1 = 15.
示例 2:
輸入:matrix =
[
[1,0,1],
[1,1,0],
[1,1,0]
]
輸出:7
解釋:
邊長爲 1 的正方形有 6 個。
邊長爲 2 的正方形有 1 個。
正方形的總數 = 6 + 1 = 7.
提示:
1 <= arr.length <= 300
1 <= arr[0].length <= 300
0 <= arr[i][j] <= 1
2.題解
官方題解用的是公式證明,左神說過,真正在做題的時候是不可能給時間做數學證明的,只能憑感覺和經驗。我當時想到了每個點比較其左邊、上邊和左上三個點的關係,但是我沒有找到關係就放棄了。
可以新建一個和原來規模一樣的矩陣,每個點的元素表示以該節點爲右下角的時候最多可以組成多少個正方形。而數學歸納法的關係就是:
在實際做題的時候,大概猜測一下就好,而且這道題在我看來也算是類型問題了。
3.源碼
leetcode已證
#include "pch.h"
#include <iostream>
#include <algorithm>
#include <queue>
#include <unordered_set>
#include <string>
#include <vector>
using namespace std;
int cc(vector<vector<int>>&mm, vector<vector<int>> &a,int x, int y)
{
int count = INT_MAX;
if (1 != mm[x][y])
return 0;
if (x - 1 >= 0)
count = min(count, a[x - 1][y]);
else
count = 0;
if (y - 1 >= 0)
count = min(count, a[x][y - 1]);
else
count = 0;
if (x - 1 >= 0 && y - 1 >= 0)
count = min(count, a[x - 1][y - 1]);
else
count = 0;
a[x][y] = count + 1;
return a[x][y];
}
int countSquares(vector<vector<int>>& matrix) {
if (matrix.empty())
return 0;
int x = matrix.size();
int count = 0;
if (x <= 0)
return 0;
int y = matrix[0].size();
vector<vector<int>>a(x, vector<int>(y));
for (int i = 0; i < x; ++i) ///<行
for (int j = 0; j < y; ++j)
count += cc(matrix, a,i, j);
return count;
}
int main()
{
vector<vector<int>>matrix;
int qq[]= {0,1,1,1};
int qq1[] = {1,1,1,1};
int qq2[] = {0,1,1,1};
vector<int>temp(begin(qq),end(qq));
vector<int>temp1(begin(qq1),end(qq1));
vector<int>temp2(begin(qq2),end(qq2));
matrix.push_back(temp);
matrix.push_back(temp1);
matrix.push_back(temp2);
cout << countSquares(matrix) << endl;
system("pause");
return 0;
}