在给定的二进制矩阵中恰好翻转一行和一列后最大化 1
给定一个二进制矩阵mat[][] 。任务是找出在翻转恰好一行的所有元素然后翻转恰好一列的所有元素后可以获得的最大1 。
例子:
Input: mat[][] = {{1, 0, 1}, {0, 1, 0}, {1, 0, 0}}
Output: 8
Explanation: Flip row 1 to get:
{{1, 0, 1},
{1, 0, 1},
{1, 0, 0}}
And then flip column 1 to get:
{{1, 1, 1},
{1, 1, 1},
{1, 1, 0}}
Input: mat[][] = { { 1, 1, 1 }, { 0, 1, 1 }, { 0, 0, 1 } }
Output: 6
Explanation: Flip row 1 to get:
{{1, 1, 1},
{1, 0, 0},
{0, 0, 1}}
And then flip column 1 to get:
{{1, 0, 1},
{1, 1, 0},
{0, 1, 1}}
方法:该方法基于预计算技术和数组遍历。按照步骤解决问题。
- 维护一个rows[]数组,该数组存储翻转相应行后获得的1的数量。
- 此外,维护一个cols[]数组,该数组存储翻转相应列后获得的1的数量。
- 然后计算整个矩阵中1的总数。
- 只需遍历每一行和列对并维护一个maxi变量,它是在翻转行和列后获得的全局最大1数量。
- 请注意,如果列和行都被翻转,它们重叠的正方形仍将保持不变。
- 考虑到这一点,在计算了行r和列c的翻转后,如果
- mat[r]处的值为 0,减去 2,因为这样会出现过度计数。
- 但如果mat[r]的值为1 ,只需添加两个,因为这样会出现计数不足。
以下是上述方法的实现:
C++
// C++ code for the above approach:
#include
using namespace std;
// Function to find the maximum 1s
int maximizeOnes(vector >& mat,
int n, int m)
{
// int n = arr.size();
// int m = arr[0].size();
vector rows(n);
vector cols(m);
int total = 0, maxi = INT_MIN, sum = 0;
for (int i = 0; i < m; i++) {
// Sum is a temporary tracker
// For each row and column
sum = 0;
for (int j = 0; j < n; j++) {
sum += mat[j][i] == 0 ? 1 : -1;
}
// Count of 1's after flip
// In each column
cols[i] = sum;
}
for (int i = 0; i < n; i++) {
sum = 0;
for (int j = 0; j < m; j++) {
sum += mat[i][j] == 0 ? 1 : -1;
// Total number of 1s in matrix
total += mat[i][j];
}
// Count of 1's after flip
// In each row
rows[i] = sum;
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
// No. of 1's after
// Flipping row and column
int temp = cols[j] + rows[i];
// Overlapping condition
// As mentioned above
temp
+= mat[i][j] == 1 ? 2 : -2;
// Updating the global maxi value
maxi = max(maxi, temp);
}
}
return total + maxi;
}
// Driver code
int main()
{
int N = 3;
int M = 3;
vector > mat
= { { 1, 0, 1 }, { 0, 1, 0 }, { 1, 0, 0 } };
cout << maximizeOnes(mat, N, M) << "\n";
return 0;
}
Java
// JAVA code for the above approach:
import java.util.*;
class GFG
{
// Function to find the maximum 1s
public static int
maximizeOnes(ArrayList > mat, int n,
int m)
{
// int n = arr.size();
// int m = arr[0].size();
int rows[] = new int[n];
int cols[] = new int[m];
int total = 0, maxi = Integer.MIN_VALUE, sum = 0;
for (int i = 0; i < m; i++) {
// Sum is a temporary tracker
// For each row and column
sum = 0;
for (int j = 0; j < n; j++) {
sum += mat.get(j).get(i) == 0 ? 1 : -1;
}
// Count of 1's after flip
// In each column
cols[i] = sum;
}
for (int i = 0; i < n; i++) {
sum = 0;
for (int j = 0; j < m; j++) {
sum += mat.get(i).get(j) == 0 ? 1 : -1;
// Total number of 1s in matrix
total += mat.get(i).get(j);
}
// Count of 1's after flip
// In each row
rows[i] = sum;
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
// No. of 1's after
// Flipping row and column
int temp = cols[j] + rows[i];
// Overlapping condition
// As mentioned above
temp += mat.get(i).get(j) == 1 ? 2 : -2;
// Updating the global maxi value
maxi = Math.max(maxi, temp);
}
}
return total + maxi;
}
// Driver code
public static void main(String[] args)
{
int N = 3;
int M = 3;
ArrayList > mat
= new ArrayList >();
ArrayList temp1 = new ArrayList(
Arrays.asList(1, 0, 1));
ArrayList temp2 = new ArrayList(
Arrays.asList(0, 1, 0));
ArrayList temp3 = new ArrayList(
Arrays.asList(1, 0, 0));
mat.add(temp1);
mat.add(temp2);
mat.add(temp3);
System.out.println(maximizeOnes(mat, N, M));
}
}
// This code is contributed by Taranpreet
Python3
# Python code for the above approach
# Function to find the maximum 1s
import sys
def maximizeOnes(mat,n, m):
# int n = arr.size();
# int m = arr[0].size();
rows = [0]*n
cols = [0]*m
total,maxi,sum = 0,-sys.maxsize-1,0
for i in range(m):
# Sum is a temporary tracker
# For each row and column
sum = 0
for j in range(n):
sum += 1 if mat[j][i] == 0 else -1
# Count of 1's after flip
# In each column
cols[i] = sum
for i in range(n):
sum = 0
for j in range(m):
sum += 1 if mat[i][j] == 0 else -1
# Total number of 1s in matrix
total += mat[i][j]
# Count of 1's after flip
# In each row
rows[i] = sum
for i in range(n):
for j in range(m):
# No. of 1's after
# Flipping row and column
temp = cols[j] + rows[i]
# Overlapping condition
# As mentioned above
temp += 2 if mat[i][j] == 1 else -2
# Updating the global maxi value
maxi = max(maxi, temp)
return total + maxi
# Driver code
N = 3
M = 3
mat = [[1, 0, 1], [0, 1, 0], [1, 0, 0]]
print(maximizeOnes(mat, N, M))
# This code is contributed by shinjanpatra
C#
// C# code for the above approach:
using System;
class GFG {
// Function to find the maximum 1s
static int maximizeOnes(int[, ] mat, int n, int m)
{
// int n = arr.size();
// int m = arr[0].size();
int[] rows = new int[n];
int[] cols = new int[m];
int total = 0, maxi = Int32.MinValue, sum = 0;
for (int i = 0; i < m; i++) {
// Sum is a temporary tracker
// For each row and column
sum = 0;
for (int j = 0; j < n; j++) {
sum += mat[j, i] == 0 ? 1 : -1;
}
// Count of 1's after flip
// In each column
cols[i] = sum;
}
for (int i = 0; i < n; i++) {
sum = 0;
for (int j = 0; j < m; j++) {
sum += mat[i, j] == 0 ? 1 : -1;
// Total number of 1s in matrix
total += mat[i, j];
}
// Count of 1's after flip
// In each row
rows[i] = sum;
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
// No. of 1's after
// Flipping row and column
int temp = cols[j] + rows[i];
// Overlapping condition
// As mentioned above
temp += mat[i, j] == 1 ? 2 : -2;
// Updating the global maxi value
maxi = Math.Max(maxi, temp);
}
}
return total + maxi;
}
// Driver code
public static void Main()
{
int N = 3;
int M = 3;
int[, ] mat
= { { 1, 0, 1 }, { 0, 1, 0 }, { 1, 0, 0 } };
Console.WriteLine(maximizeOnes(mat, N, M));
}
}
// This code is contributed by Samim Hossain Mondal.
Javascript
输出
8
时间复杂度: O(N * M)
辅助空间: O(N + M)