📌  相关文章
📜  给定大小的子矩阵,最大为 1

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

给定一个二进制矩阵mat[][]和一个整数K ,任务是找到大小为 K*K 的子矩阵,使得它在矩阵中包含最大数量的 1。

例子:

方法:思路是使用滑动窗口技术来解决这个问题,在这种技术中,我们一般先计算一个窗口的值,然后将窗口一个一个滑动来计算每个大小为K的窗口的解。
要计算最大 1 的子矩阵,请使用滑动窗口技术计算大小为 K 的每个可能窗口的行中 1 的数量,并以矩阵的形式存储 1 的计数。

例如:

Let the matrix be {{1,0,1}, {1, 1, 0}} and K = 2

For Row 1 -
Subarray 1: (1, 0), Count of 1 = 1
Subarray 2: (0, 1), Count of 1 = 1

For Row 2 -
Subarray 1: (1, 1), Count of 1 = 2
Subarray 2: (1, 0), Count of 1 = 1

Then the final matrix for count of 1's will be -
[ 1, 1 ]
[ 2, 1 ]

类似地,在该矩阵的每一列上应用滑动窗口技术,计算每个可能的子矩阵中 1 的计数,并从这些计数中取出最大值。

下面是上述方法的实现:

C++
// C++ implementation to find the
// maximum count of 1's in
// submatrix of order K
#include 
using namespace std;
 
// Function to find the maximum
// count of 1's in the
// submatrix of order K
int maxCount(vector> &mat, int k) {
 
    int n = mat.size();
    int m = mat[0].size();
    vector> a;
 
    // Loop to find the count of 1's
    // in every possible windows
    // of rows of matrix
    for (int e = 0; e < n; ++e){
        vector s = mat[e];
        vector q;
        int    c = 0;
         
        // Loop to find the count of
        // 1's in the first window
        int i;
        for (i = 0; i < k; ++i)
            if(s[i] == 1)
                c += 1;
 
        q.push_back(c);
        int p = s[0];
         
        // Loop to find the count of
        // 1's in the remaining windows
        for (int j = i + 1; j < m; ++j) {
            if(s[j] == 1)
                c+= 1;
            if(p == 1)
                c-= 1;
            q.push_back(c);
            p = s[j-k + 1];
        }
        a.push_back(q);
    }
 
    vector> b;
    int max = 0;
     
    // Loop to find the count of 1's
    // in every possible submatrix
    for (int i = 0; i < a[0].size(); ++i) {
        int c = 0;
        int p = a[0][i];
         
        // Loop to find the count of
        // 1's in the first window
        int j;
        for (j = 0; j < k; ++j) {
            c+= a[j][i];
        }
        vector q;
        if (c>max)
            max = c;
        q.push_back(c);
         
        // Loop to find the count of
        // 1's in the remaining windows
        for (int l = j + 1; j < n; ++j) {
            c+= a[l][i];
            c-= p;
            p = a[l-k + 1][i];
            q.push_back(c);
            if (c > max)
                max = c;
        }
 
        b.push_back(q);
    }
 
    return max;
}
 
// Driver code
int main()
{
    vector> mat = {{1, 0, 1}, {1, 1, 0}, {0, 1, 0}};
    int k = 3;
     
    // Function call
    cout<< maxCount(mat, k);
 
    return 0;
}


Java
// Java implementation to find the
// maximum count of 1's in
// submatrix of order K
import java.io.*;
import java.util.*;
 
class GFG{
 
// Function to find the maximum
// count of 1's in the
// submatrix of order K
static int maxCount(ArrayList > mat, int k)
{
    int n = mat.size();
    int m = mat.get(0).size();
    ArrayList> a = new ArrayList>();
     
    // Loop to find the count of 1's
    // in every possible windows
    // of rows of matrix
    for(int e = 0; e < n; ++e)
    {
        ArrayList s = mat.get(e);
        ArrayList q = new ArrayList();
        int c = 0;
         
        // Loop to find the count of
        // 1's in the first window
        int i;
        for(i = 0; i < k; ++i)
        {
            if (s.get(i) == 1)
            {
                c += 1;
            }
        }
        q.add(c);
        int p = s.get(0);
         
        // Loop to find the count of
        // 1's in the remaining windows
        for(int j = i + 1; j < m; ++j)
        {
            if (s.get(j) == 1)
            {
                c += 1;
            }
            if (p == 1)
            {
                c -= 1;
            }
            q.add(c);
            p = s.get(j - k + 1);
        }
        a.add(q);
    }
     
    ArrayList> b = new ArrayList>();
    int max = 0;
     
    // Loop to find the count of 1's
    // in every possible submatrix
    for(int i = 0; i < a.get(0).size(); ++i)
    {
        int c = 0;
        int p = a.get(0).get(i);
         
        // Loop to find the count of
        // 1's in the first window
        int j;
        for(j = 0; j < k; ++j)
        {
            c += a.get(j).get(i);
        }
        ArrayList q = new ArrayList();
         
        if (c > max)
        {
            max = c;
        }
        q.add(c);
         
        // Loop to find the count of
        // 1's in the remaining windows
        for(int l = j + 1; j < n; ++j)
        {
             
            c += a.get(l).get(i);
            c -= p;
            p = a.get(l - k + 1).get(i);
            q.add(c);
             
            if (c > max)
            {
                max = c;
            }
        }
        b.add(q);
    }
    return max;
}
 
// Driver code
public static void main(String[] args)
{
    ArrayList> mat = new ArrayList>();
    mat.add(new ArrayList(Arrays.asList(1, 0, 1)));
    mat.add(new ArrayList(Arrays.asList(1, 1, 0)));
    mat.add(new ArrayList(Arrays.asList(0, 1, 0)));
    int k = 3;
     
    // Function call
    System.out.println(maxCount(mat, k));
}
}
 
// This code is contributed by avanitrachhadiya2155


Python3
# Python3 implementation to find the
# maximum count of 1's in
# submatrix of order K
 
# Function to find the maximum
# count of 1's in the
# submatrix of order K
def maxCount(mat, k):
    n, m = len(mat), len(mat[0])
    a =[]
     
    # Loop to find the count of 1's
    # in every possible windows
    # of rows of matrix
    for e in range(n):
        s = mat[e]
        q =[]
        c = 0
         
        # Loop to find the count of
        # 1's in the first window
        for i in range(k):
            if s[i] == 1:
                c += 1
        q.append(c)
        p = s[0]
         
        # Loop to find the count of
        # 1's in the remaining windows
        for j in range(i + 1, m):
            if s[j]==1:
                c+= 1
            if p ==1:
                c-= 1
            q.append(c)
            p = s[j-k + 1]
        a.append(q)
    b =[]
    max = 0
     
    # Loop to find the count of 1's
    # in every possible submatrix
    for i in range(len(a[0])):
        c = 0
        p = a[0][i]
         
        # Loop to find the count of
        # 1's in the first window
        for j in range(k):
            c+= a[j][i]
        q =[]
        if c>max:
            max = c
        q.append(c)
         
        # Loop to find the count of
        # 1's in the remaining windows
        for l in range(j + 1, n):
            c+= a[l][i]
            c-= p
            p = a[l-k + 1][i]
            q.append(c)
            if c > max:
                max = c
        b.append(q)
    return max
     
# Driver Code
if __name__ == "__main__":
    mat = [[1, 0, 1], [1, 1, 0], [0, 1, 0]]
    k = 3
     
    # Function call
    print(maxCount(mat, k))


C#
// C# implementation to find the
// maximum count of 1's in
// submatrix of order K
using System;
using System.Collections.Generic;
 
class GFG{
     
// Function to find the maximum
// count of 1's in the
// submatrix of order K
static int maxCount(List> mat, int k)
{
    int n = mat.Count;
    int m = mat[0].Count;
    List> a = new List>();
     
    // Loop to find the count of 1's
    // in every possible windows
    // of rows of matrix
    for(int e = 0; e < n; ++e)
    {
        List s = mat[e];
        List q = new List();
        int c = 0;
         
        // Loop to find the count of
        // 1's in the first window
        int i;
         
        for(i = 0; i < k; ++i)
        {
            if (s[i] == 1)
            {
                c++;
            }
        }
        q.Add(c);
        int p = s[0];
         
        // Loop to find the count of
        // 1's in the remaining windows
        for(int j = i + 1; j < m; ++j)
        {
            if (s[j] == 1)
            {
                c++;
            }
            if (p == 1)
            {
                c--;
            }
            q.Add(c);
            p = s[j - k + 1];
        }
        a.Add(q);
    }
    List> b = new List>();
    int max = 0;
     
    // Loop to find the count of 1's
    // in every possible submatrix
    for(int i = 0; i < a[0].Count; ++i)
    {
        int c = 0;
        int p = a[0][i];
         
        // Loop to find the count of
        // 1's in the first window
        int j;
        for(j = 0; j < k; ++j)
        {
            c += a[j][i];
        }
         
        List q = new List();
         
        if (c > max)
        {
            max = c;
        }
        q.Add(c);
         
        // Loop to find the count of
        // 1's in the remaining windows
        for(int l = j + 1; j < n; ++j)
        {
            c += a[l][i];
            c -= p;
            p = a[l - k + 1][i];
            q.Add(c);
             
            if (c > max)
            {
                max = c;
            }
        }
        b.Add(q);
    }
    return max;
}
 
// Driver code
static public void Main()
{
    List> mat = new List>();
    mat.Add(new List(){1, 0, 1});
    mat.Add(new List(){1, 1, 0});
    mat.Add(new List(){0, 1, 0});
    int k = 3;
     
    // Function call
    Console.WriteLine(maxCount(mat, k));
}
}
 
// This code is contributed by rag2127


C++14
// C++14 approach
#include 
using namespace std;
 
int findMaxK(vector> dp,
             int k, int n, int m)
{
     
    // Assign first kXk matrix initial
    // value as max
    int max_ = dp[k - 1][k - 1];
     
    for(int i = k; i < n; i++)
    {
        int su = dp[i - k][k - 1];
            if (max_ < su)
                max_ = su;
    }
    for(int j = k; j < m; j++)
    {
        int su = dp[k - 1][j - k];
            if (max_< su)
                max_ = su;
    }
    for(int i = k; i < n; i++)
    {
        for(int j = k; j < m; j++)
        {
            int su = dp[i][j] +
                     dp[i - k][j - k] -
                     dp[i - k][j] -
                     dp[i][j - k];
                      
            if( max_ < su)
                max_ = su;
        }
    }
    return max_;
}
 
vector> buildDPdp(vector> mat,
                              int k, int n, int m)
{
     
    // Assign mXn dp list to 0
    vector> dp(n, vector(m, 0));
 
    // Assign initial starting value
    dp[0][0] = mat[0][0];
 
    for(int i = 1; i < m; i++)
        dp[0][i] += (dp[0][i - 1] + mat[0][i]);
 
    for(int i = 1; i < n; i++)
        dp[i][0] += (dp[i - 1][0] + mat[i][0]);
 
    for(int i = 1; i < n; i++)
        for(int j = 1; j < m; j++)
            dp[i][j] = dp[i - 1][j] +
                       dp[i][j - 1] +
                       mat[i][j] -
                       dp[i - 1][j - 1];
 
    return dp;
}
 
int maxOneInK(vector> mat, int k)
{
     
    // n is colums
    int n = mat.size();
 
    // m is rows
    int m = mat[0].size();
 
    // Build dp list
    vector> dp = buildDPdp(
        mat, k, n, m);
 
    // Call the function and return its value
    return findMaxK(dp, k, n, m);
}
 
// Driver Code
int main()
{
     
    // mXn matrix
    vector> mat = { { 1, 0, 1 },
                                { 1, 1, 0 },
                                { 0, 1, 0 } };
 
    int k = 3;
 
    // Calling function
    cout << maxOneInK(mat, k);
 
    return 0;
}
 
// This code is contributed by mohit kumar 29


Python3
#python3 approach
 
def findMaxK(dp,k,n,m):
     
    # assign first kXk matrix initial value as max
    max_ = dp[k-1][k-1]
     
     
    for i in range(k,n):
        su = dp[i-k][k-1]
        if max_ < su:
            max_ = su
     
    for j in range(k,m):
        su = dp[k-1][i-k]
        if max_< su:
            max_ = su
             
    for i in range(k,n):
        for j in range(k,m):
            su = dp[i][j] + dp[i-k][j-k] - dp[i-k][j] - dp[i][j-k]
            if max_ < su:
                max_ = su
             
    return max_
     
def buildDPdp(mat,k,n,m):
     
    # assign mXn dp list to 0
    dp = [[0 for i in range(m)] for j in range(n)]
     
    # assign initial starting value
    dp[0][0] = mat[0][0]
     
    for i in range(1,m):
        dp[0][i] += (dp[0][i-1]+mat[0][i])
     
    for i in range(1,n):
        dp[i][0] += (dp[i-1][0]+mat[i][0])
     
     
    for i in range(1,n):
        for j in range(1,m):
            dp[i][j] = dp[i-1][j] + dp[i][j-1] + mat[i][j] - dp[i-1][j-1]
 
    return dp
 
def maxOneInK(mat,k):
     
    # n is colums
    n = len(mat)
     
    # m is rows
    m = len(mat[0])
     
    #build dp list
    dp = buildDPdp(mat,k,n,m)
     
    # call the function and return its value
    return findMaxK(dp,k,n,m)
     
     
         
 
def main():
    # mXn matrix
    mat = [[1, 0, 1], [1, 1, 0], [0, 1, 0]]
     
    k = 3
     
    #callind function
    print(maxOneInK(mat,k))
 
#driver code
main()
 
 
#This code is contributed by Tokir Manva


输出:
5

性能分析:

  • 时间复杂度:与上述方法一样,有两个循环需要 O(N*M) 时间,因此时间复杂度将为O(N*M)
  • 空间复杂度:与上述方法一样,使用了额外的空间,因此空间复杂度为O(N)

方法 2:[动态规划方法]在这种技术中,我们使用给定的mat [][]数组计算dp[][]矩阵。在dp[][]数组中,我们计算 1 的数量,直到索引(i,j)使用先前的dp[][]值并将其存储在dp[i][j] 中

算法 :

1) Construct a dp[][] matrix and assign all elements to 0

    initial dp[0][0] = mat[0][0]

    a) compute first row and column of the dp matrix:

        i) for first row:

            dp[0][i] = dp[0][i-1] + mat[0][i]

        ii) for first column:

            dp[i][0] = dp[i-1][0] + mat[i][0]

    b) now compute remaining dp matrix from (1,1) to (n,m):

        dp[i][j] = mat[i][j] + dp[i-1][j] + dp[i][j-1] - dp[i-1][j-1]

2)now, we find the maximum 1's in k X k sub matrix:

    a) initially we assign max = dp[k-1][k-1]

    b) now first we have to check maximum for k-1 row and k-1 column:

        i) for k-1 row:

            if dp[k-1][j] - dp[k-1][j-k] > max:

                max = dp[k-1][j] - dp[k-1][j-k]

        ii) for k-1 column:

            if dp[i][k-1] - dp[i-k][k-1] > max:

                max = dp[i][k-1] - dp[i-k][k-1]

    c) now, we check max for (k to n) row and (k to m) column:

        for i from k to n-1:

            for j from k to m-1:

                if dp[i][j] + dp[i-k][j-k] - dp[i-k][j] - dp[i][j-k] > max:

                    max = dp[i][j] + dp[i-k][j-k] - dp[i-k][j] - dp[i][j-k]

 now just return the max value.

下面是上述方法的实现:

C++14

// C++14 approach
#include 
using namespace std;
 
int findMaxK(vector> dp,
             int k, int n, int m)
{
     
    // Assign first kXk matrix initial
    // value as max
    int max_ = dp[k - 1][k - 1];
     
    for(int i = k; i < n; i++)
    {
        int su = dp[i - k][k - 1];
            if (max_ < su)
                max_ = su;
    }
    for(int j = k; j < m; j++)
    {
        int su = dp[k - 1][j - k];
            if (max_< su)
                max_ = su;
    }
    for(int i = k; i < n; i++)
    {
        for(int j = k; j < m; j++)
        {
            int su = dp[i][j] +
                     dp[i - k][j - k] -
                     dp[i - k][j] -
                     dp[i][j - k];
                      
            if( max_ < su)
                max_ = su;
        }
    }
    return max_;
}
 
vector> buildDPdp(vector> mat,
                              int k, int n, int m)
{
     
    // Assign mXn dp list to 0
    vector> dp(n, vector(m, 0));
 
    // Assign initial starting value
    dp[0][0] = mat[0][0];
 
    for(int i = 1; i < m; i++)
        dp[0][i] += (dp[0][i - 1] + mat[0][i]);
 
    for(int i = 1; i < n; i++)
        dp[i][0] += (dp[i - 1][0] + mat[i][0]);
 
    for(int i = 1; i < n; i++)
        for(int j = 1; j < m; j++)
            dp[i][j] = dp[i - 1][j] +
                       dp[i][j - 1] +
                       mat[i][j] -
                       dp[i - 1][j - 1];
 
    return dp;
}
 
int maxOneInK(vector> mat, int k)
{
     
    // n is colums
    int n = mat.size();
 
    // m is rows
    int m = mat[0].size();
 
    // Build dp list
    vector> dp = buildDPdp(
        mat, k, n, m);
 
    // Call the function and return its value
    return findMaxK(dp, k, n, m);
}
 
// Driver Code
int main()
{
     
    // mXn matrix
    vector> mat = { { 1, 0, 1 },
                                { 1, 1, 0 },
                                { 0, 1, 0 } };
 
    int k = 3;
 
    // Calling function
    cout << maxOneInK(mat, k);
 
    return 0;
}
 
// This code is contributed by mohit kumar 29

蟒蛇3

#python3 approach
 
def findMaxK(dp,k,n,m):
     
    # assign first kXk matrix initial value as max
    max_ = dp[k-1][k-1]
     
     
    for i in range(k,n):
        su = dp[i-k][k-1]
        if max_ < su:
            max_ = su
     
    for j in range(k,m):
        su = dp[k-1][i-k]
        if max_< su:
            max_ = su
             
    for i in range(k,n):
        for j in range(k,m):
            su = dp[i][j] + dp[i-k][j-k] - dp[i-k][j] - dp[i][j-k]
            if max_ < su:
                max_ = su
             
    return max_
     
def buildDPdp(mat,k,n,m):
     
    # assign mXn dp list to 0
    dp = [[0 for i in range(m)] for j in range(n)]
     
    # assign initial starting value
    dp[0][0] = mat[0][0]
     
    for i in range(1,m):
        dp[0][i] += (dp[0][i-1]+mat[0][i])
     
    for i in range(1,n):
        dp[i][0] += (dp[i-1][0]+mat[i][0])
     
     
    for i in range(1,n):
        for j in range(1,m):
            dp[i][j] = dp[i-1][j] + dp[i][j-1] + mat[i][j] - dp[i-1][j-1]
 
    return dp
 
def maxOneInK(mat,k):
     
    # n is colums
    n = len(mat)
     
    # m is rows
    m = len(mat[0])
     
    #build dp list
    dp = buildDPdp(mat,k,n,m)
     
    # call the function and return its value
    return findMaxK(dp,k,n,m)
     
     
         
 
def main():
    # mXn matrix
    mat = [[1, 0, 1], [1, 1, 0], [0, 1, 0]]
     
    k = 3
     
    #callind function
    print(maxOneInK(mat,k))
 
#driver code
main()
 
 
#This code is contributed by Tokir Manva
输出:
5

性能分析:

  • 时间复杂度:在上面的动态程序方法中,我们必须计算需要 O(N*M) 时间的NXM dp 矩阵,因此时间复杂度将为O(N*M)
  • 空间复杂度:与上述方法一样,有额外的空间用于制作 dp NXM矩阵,因此空间复杂度为O(N*M)

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