给定一个二进制矩阵mat[][]和一个整数K ,任务是找到大小为 K*K 的子矩阵,使得它在矩阵中包含最大数量的 1。
例子:
Input: mat[][] = {{1, 0, 1}, {1, 1, 0}, {1, 0, 0}}, K = 2
Output: 3
Explanation:
In the given matrix, there are 4 sub-matrix of order 2*2,
|1 0| |0 1| |1 1| |1 0|
|1 1|, |1 0|, |1 0|, |0 0|
Out of these sub-matrix, two matrix contains 3, 1’s.
Input: mat[][] = {{1, 0}, {0, 1}}, K = 1
Output: 1
Explanation:
In the given matrix, there are 4 sub-matrix of order 1*1,
|1|, |0|, |1|, |0|
Out of these sub-matrix, two matrix contains 1, 1’s.
方法:思路是使用滑动窗口技术来解决这个问题,在这种技术中,我们一般先计算一个窗口的值,然后将窗口一个一个滑动来计算每个大小为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