📜  检查矩阵是否包含以 0 作为边界元素的方形子矩阵

📅  最后修改于: 2021-09-07 02:28:10             🧑  作者: Mango

给定一个N*N二进制矩阵arr[][] ,任务是检查矩阵是否包含大小至少为2 x 2的正方形,其边界仅由0 组成

例子:

方法:

  1. 正方形由其最顶部和最底部的行以及最左侧和最右侧的列定义。
  2. 给定形成有效正方形的一对行和一对列,您可以轻松确定相关正方形是否是带有两个 for 循环的零正方形。
  3. 需要迭代输入矩阵 arr[][] 中的每个有效方格。
  4. 我们可以从最外面的正方形开始迭代,然后在矩阵中递归地向内移动。
  5. 在向内移动时,从 (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)
  6. 由于这个问题有很多重叠的子问题,所以我们需要使用缓存/记忆来避免重复计算。

下面是上述方法的实现:

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)

高效的方法:为了优化上述方法,我们需要遵循以下步骤:

  1. 我们需要为矩阵中的每个元素预先计算两个值:每个元素右侧的 0 数量(包括元素本身)和每个元素下方的 0 数量(包括元素本身)。
  2. 我们可以通过从右下角开始迭代矩阵并通过从右到左遍历每一行向上移动来计算这些值。
  3. 一旦我们计算了矩阵,那么我们可以在恒定时间内检查正方形的边界是否由全 0 组成。
  4. 要检查正方形的边界,我们只需要查看任何正方形两个顶角下方的 0 数量以及同一正方形两个左角右侧的 0 数量。

如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live