给定一个N*N二进制矩阵arr[][] ,任务是检查矩阵是否包含大小至少为2 x 2的正方形,其边界仅由0 组成。
例子:
Input:
arr[][] = {
{1, 1, 1, 0, 1, 0},
{0, 0, 0, 0, 0, 1},
{0, 1, 1, 1, 0, 1},
{0, 0, 0, 1, 0, 1},
{0, 1, 1, 1, 0, 1},
{0, 0, 0, 0, 0, 1}
}
Output: True
Explanation:
Since, arr[][] contains square matrix with all 0’s at boundary, so answer is True.
{
{ , , , , , },
{0, 0, 0, 0, 0, },
{0, , , , 0, },
{0, , , , 0, },
{0, , , , 0, },
{0, 0, 0, 0, 0, }
}
Input:
arr[][] = {
{1, 1, 1, 0, 1, 0},
{0, 0, 0, 0, 0, 1},
{0, 1, 1, 1, 0, 1},
{0, 0, 0, 1, 1, 1},
{0, 1, 1, 1, 0, 1},
{0, 0, 0, 0, 0, 1}
}
Output: False
Explanation: There is no square in the matrix whose borders are made up of only 0s.
方法:
- 正方形由其最顶部和最底部的行以及最左侧和最右侧的列定义。
- 给定形成有效正方形的一对行和一对列,您可以轻松确定相关正方形是否是带有两个 for 循环的零正方形。
- 需要迭代输入矩阵 arr[][] 中的每个有效方格。
- 我们可以从最外面的正方形开始迭代,然后在矩阵中递归地向内移动。
- 在向内移动时,从 (r1, c1) 和 (r2, c2) 我们有 5 个选项,它们将生成方阵:-
a) (r1 + 1, c1 + 1), (r2 – 1, c2 – 1)
b) (r1, c1 + 1), (r2 – 1, c2)
c) (r1 + 1, c1), (r2, c2 – 1)
d) (r1 + 1, c1 + 1), (r2, c2)
e) (r1, c1), (r2 – 1, c2 – 1) - 由于这个问题有很多重叠的子问题,所以我们需要使用缓存/记忆来避免重复计算。
下面是上述方法的实现:
C++
// C++ implementation of the above approach
#include
using namespace std;
bool hasSquareOfZeroes(
vector >& matrix,
int r1, int c1, int r2, int c2,
unordered_map& cache);
bool isSquareOfZeroes(
vector >& matrix,
int r1, int c1,
int r2, int c2);
// Function checks if square
// with all 0's in boundary
// exists in the matrix
bool squareOfZeroes(
vector > matrix)
{
int lastIdx = matrix.size() - 1;
unordered_map cache;
return hasSquareOfZeroes(
matrix,
0, 0,
lastIdx,
lastIdx,
cache);
}
// Function iterate inward in
// the matrix and checks the
// square obtained and memoize/cache
// the result to avoid duplicate computation
// r1 is the top row,
// c1 is the left col
// r2 is the bottom row,
// c2 is the right
bool hasSquareOfZeroes(
vector >& matrix,
int r1, int c1, int r2, int c2,
unordered_map& cache)
{
if (r1 >= r2 || c1 >= c2)
return false;
string key = to_string(r1) + '-'
+ to_string(c1) + '-'
+ to_string(r2) + '-'
+ to_string(c2);
if (cache.find(key) != cache.end())
return cache[key];
cache[key]
= isSquareOfZeroes(
matrix, r1, c1, r2, c2)
|| hasSquareOfZeroes(
matrix, r1 + 1, c1 + 1,
r2 - 1, c2 - 1, cache)
|| hasSquareOfZeroes(
matrix, r1, c1 + 1,
r2 - 1, c2, cache)
|| hasSquareOfZeroes(
matrix, r1 + 1, c1,
r2, c2 - 1, cache)
|| hasSquareOfZeroes(
matrix, r1 + 1, c1 + 1,
r2, c2, cache)
|| hasSquareOfZeroes(
matrix, r1, c1,
r2 - 1, c2 - 1, cache);
return cache[key];
}
// Function checks if the
// boundary of the square
// consists of 0's
bool isSquareOfZeroes(
vector >& matrix,
int r1, int c1,
int r2, int c2)
{
for (int row = r1; row < r2 + 1; row++) {
if (matrix[row][c1] != 0
|| matrix[row][c2] != 0)
return false;
}
for (int col = c1; col < c2 + 1; col++) {
if (matrix[r1][col] != 0
|| matrix[r2][col] != 0)
return false;
}
return true;
}
// Driver Code
int main()
{
vector > matrix{
{ 1, 1, 1, 0, 1, 0 },
{ 0, 0, 0, 0, 0, 1 },
{ 0, 1, 1, 1, 0, 1 },
{ 0, 0, 0, 1, 0, 1 },
{ 0, 1, 1, 1, 0, 1 },
{ 0, 0, 0, 0, 0, 1 }
};
int ans;
ans = squareOfZeroes(matrix);
if (ans == 1) {
cout << "True" << endl;
}
else {
cout << "False" << endl;
}
}
Java
// Java implementation of the above approach
import java.io.*;
import java.util.*;
class GFG
{
// Function checks if square
// with all 0's in boundary
// exists in the matrix
static int squareOfZeroes(int[][] matrix)
{
int lastIdx = matrix.length - 1;
Map cache
= new HashMap();
return (hasSquareOfZeroes(matrix, 0, 0, lastIdx,
lastIdx, cache)) ? 1 : 0;
}
// Function iterate inward in
// the matrix and checks the
// square obtained and memoize/cache
// the result to avoid duplicate computation
// r1 is the top row,
// c1 is the left col
// r2 is the bottom row,
// c2 is the right
static boolean hasSquareOfZeroes(int[][] matrix, int r1, int c1,
int r2, int c2,
Map cache)
{
if (r1 >= r2 || c1 >= c2)
return false;
String key = r1 + "-" + c1 +
"-" + r2 + "-" + c2;
if (cache.containsKey(key))
return cache.get(key);
cache.put(
key,
isSquareOfZeroes(matrix, r1, c1, r2, c2)
|| hasSquareOfZeroes(matrix, r1 + 1, c1 + 1,
r2 - 1, c2 - 1, cache)
|| hasSquareOfZeroes(matrix, r1, c1 + 1,
r2 - 1, c2, cache)
|| hasSquareOfZeroes(matrix, r1 + 1, c1, r2,
c2 - 1, cache)
|| hasSquareOfZeroes(matrix, r1 + 1, c1 + 1,
r2, c2, cache)
|| hasSquareOfZeroes(matrix, r1, c1, r2 - 1,
c2 - 1, cache));
return cache.get(key);
}
// Function checks if the
// boundary of the square
// consists of 0's
static boolean isSquareOfZeroes(int[][] matrix,
int r1, int c1,
int r2, int c2)
{
for (int row = r1; row < r2 + 1; row++)
{
if (matrix[row][c1] != 0
|| matrix[row][c2] != 0)
return false;
}
for (int col = c1; col < c2 + 1; col++)
{
if (matrix[r1][col] != 0
|| matrix[r2][col] != 0)
return false;
}
return true;
}
// Driver Code
public static void main(String[] args)
{
int[][] matrix = {
{ 1, 1, 1, 0, 1, 0 }, { 0, 0, 0, 0, 0, 1 },
{ 0, 1, 1, 1, 0, 1 }, { 0, 0, 0, 1, 0, 1 },
{ 0, 1, 1, 1, 0, 1 }, { 0, 0, 0, 0, 0, 1 }
};
int ans;
ans = squareOfZeroes(matrix);
if (ans == 1)
{
System.out.println("True");
}
else
{
System.out.println("False");
}
}
}
// This code is contributed by jitin
Python3
# Python3 implementation of the above approach
# Function checks if square
# with all 0's in boundary
# exists in the matrix
def squareOfZeroes():
global matrix, cache
lastIdx = len(matrix) - 1
return hasSquareOfZeroes(0, 0, lastIdx,
lastIdx)
# Function iterate inward in
# the matrix and checks the
# square obtained and memoize/cache
# the result to avoid duplicate computation
# r1 is the top row,
# c1 is the left col
# r2 is the bottom row,
# c2 is the right
def hasSquareOfZeroes(r1, c1, r2, c2):
global matrix, cache
if (r1 >= r2 or c1 >= c2):
return False
key = (str(r1) + '-' + str(c1) + '-' +
str(r2) + '-' + str(c2))
if (key in cache):
return cache[key]
cache[key] = (isSquareOfZeroes(r1, c1, r2, c2) or
hasSquareOfZeroes(r1 + 1, c1 + 1,
r2 - 1, c2 - 1))
cache[key] = (cache[key] or
hasSquareOfZeroes(r1, c1 + 1,
r2 - 1, c2) or
hasSquareOfZeroes(r1 + 1, c1,
r2, c2 - 1))
cache[key] = (cache[key] or
hasSquareOfZeroes(r1 + 1, c1 + 1,
r2, c2) or
hasSquareOfZeroes(r1, c1, r2 - 1,
c2 - 1))
return cache[key]
# Function checks if the
# boundary of the square
# consists of 0's
def isSquareOfZeroes(r1, c1, r2, c2):
global matrix
for row in range(r1, r2 + 1):
if (matrix[row][c1] != 0 or
matrix[row][c2] != 0):
return False
for col in range(c1, c2 + 1):
if (matrix[r1][col] != 0 or
matrix[r2][col] != 0):
return False
return True
# Driver Code
if __name__ == '__main__':
cache = {}
matrix = [ [ 1, 1, 1, 0, 1, 0 ],
[ 0, 0, 0, 0, 0, 1 ],
[ 0, 1, 1, 1, 0, 1 ],
[ 0, 0, 0, 1, 0, 1 ],
[ 0, 1, 1, 1, 0, 1 ],
[ 0, 0, 0, 0, 0, 1 ] ]
ans = squareOfZeroes()
if (ans == 1):
print("True")
else:
print("False")
# This code is contributed by mohit kumar 29
C#
// C# implementation of the above approach
using System;
using System.Collections.Generic;
class GFG
{
// Function checks if square
// with all 0's in boundary
// exists in the matrix
static int squareOfZeroes(int[,] matrix)
{
int lastIdx = matrix.GetLength(0) - 1;
Dictionary cache = new Dictionary();
if(hasSquareOfZeroes(matrix, 0, 0, lastIdx,lastIdx, cache))
{
return 1;
}
else
{
return 0;
}
}
// Function iterate inward in
// the matrix and checks the
// square obtained and memoize/cache
// the result to avoid duplicate computation
// r1 is the top row,
// c1 is the left col
// r2 is the bottom row,
// c2 is the right
static bool hasSquareOfZeroes(int[,] matrix, int r1,
int c1,int r2, int c2,
Dictionary cache)
{
if (r1 >= r2 || c1 >= c2)
{
return false;
}
string key = r1 + "-" + c1 + "-" + r2 + "-" + c2;
if (cache.ContainsKey(key))
{
return cache[key];
}
cache[key] = (isSquareOfZeroes(matrix, r1, c1, r2, c2) ||
hasSquareOfZeroes(matrix, r1 + 1, c1 + 1,
r2 - 1, c2 - 1, cache) ||
hasSquareOfZeroes(matrix, r1, c1 + 1,r2 - 1,
c2, cache) ||
hasSquareOfZeroes(matrix, r1 + 1, c1, r2,
c2 - 1, cache) ||
hasSquareOfZeroes(matrix, r1 + 1, c1 + 1,
r2, c2, cache) ||
hasSquareOfZeroes(matrix, r1, c1, r2 - 1,
c2 - 1, cache));
return cache[key];
}
// Function checks if the
// boundary of the square
// consists of 0's
static bool isSquareOfZeroes(int[,] matrix, int r1,
int c1,int r2, int c2)
{
for (int row = r1; row < r2 + 1; row++)
{
if (matrix[row,c1] != 0 || matrix[row,c2] != 0)
{
return false;
}
}
for (int col = c1; col < c2 + 1; col++)
{
if (matrix[r1,col] != 0 || matrix[r2,col] != 0)
{
return false;
}
}
return true;
}
// Driver Code
static public void Main ()
{
int[,] matrix = {{ 1, 1, 1, 0, 1, 0 },
{ 0, 0, 0, 0, 0, 1 },
{ 0, 1, 1, 1, 0, 1 },
{ 0, 0, 0, 1, 0, 1 },
{ 0, 1, 1, 1, 0, 1 },
{ 0, 0, 0, 0, 0, 1 }};
int ans;
ans = squareOfZeroes(matrix);
if(ans == 1)
{
Console.WriteLine("True");
}
else
{
Console.WriteLine("False");
}
}
}
// This code is contributed by avanitrachhadiya2155
Javascript
True
时间复杂度: O(N^4)
空间复杂度: O(N^3)
高效的方法:为了优化上述方法,我们需要遵循以下步骤:
- 我们需要为矩阵中的每个元素预先计算两个值:每个元素右侧的 0 数量(包括元素本身)和每个元素下方的 0 数量(包括元素本身)。
- 我们可以通过从右下角开始迭代矩阵并通过从右到左遍历每一行向上移动来计算这些值。
- 一旦我们计算了矩阵,那么我们可以在恒定时间内检查正方形的边界是否由全 0 组成。
- 要检查正方形的边界,我们只需要查看任何正方形两个顶角下方的 0 数量以及同一正方形两个左角右侧的 0 数量。