给定一个N * N二进制矩阵arr [] [] ,任务是检查矩阵是否包含至少大小为2 x 2的正方形,其边界仅由0 s组成。
例子:
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
True
时间复杂度: O(N ^ 4)
空间复杂度: O(N ^ 3)
高效的方法:为了优化上述方法,我们需要遵循以下步骤:
- 我们需要为矩阵中的每个元素预先计算两个值:每个元素右边的0(包括元素本身)的数目和每个元素下方(包括元素本身)的0的数目。
- 我们可以通过从右下角开始遍历矩阵并通过从右向左遍历每一行向上移动矩阵来计算这些值。
- 一次,我们计算了矩阵,然后可以检查正方形的边界,它是否由恒定时间内的全0组成。
- 要检查正方形的边界,我们只需要查看任何正方形的两个上角下方的0数量,以及同一正方形的两个左角右侧的0数量。
如果您希望与行业专家一起参加现场课程,请参阅《 Geeks现场课程》和《 Geeks现场课程美国》。