给定大小为N * M的2D矩阵mat [] []和正整数K ,任务是找到需要删除的最小矩形子矩阵的面积,以使矩阵中其余元素的总和为可被K整除。
例子:
Input: mat[][] = { {6, 2, 6}, {3, 2, 8}, {2, 5, 3} }, K = 3
Output: 2
Explanation:
Remove the sub-matrix { mat[1][1], mat[2][1] } from the given matrix.
Since the sum of the remaining matrix is equal to 30 which is divisible by K(=3). Therefore, the required output is 1 * 2 = 2.
Input: mat[][] = { {16, 2, 6, 13}, {33, 21, 8, 8}, {31, 5, 3, 11} }, K = 15
Output: 3
方法:请按照以下步骤解决问题:
- 初始化一个变量,例如S,以存储给定矩阵的所有元素之和。
- 初始化一个变量,例如min_area,以存储需要删除的最小区域,以使其余矩阵元素的总和可被K整除。
- 初始化两个变量,例如left和right ,分别存储每个子矩阵的最左列和最右列。
- 初始化一个数组,例如PrefixRowSum [N] ,其中PrefixRowSum [i]存储子矩阵的所有元素之和,其最左上的元素为(0,左)和最右下的元素为(i,右) left和right的所有可能值。
- 遍历的左,右和找到的最小的子阵列需要的长度将被删除,以使PrefixRowSum []的剩余元素的总和等于(S%K)的所有可能的值和更新min_area
- 最后,打印min_area的值。
下面是上述方法的实现:
C++
// C++ program to implement
// the above approach
#include
using namespace std;
// Function to find the length of the
// smallest subarray to be removed such
// that sum of elements is equal to S % K
int removeSmallestSubarray(int arr[], int S,
int n, int k)
{
// Remainder when total_sum
// is divided by K
int target_remainder
= S % k;
// Stores curr_remainder and the
// most recent index at which
// curr_remainder has occured
unordered_map map1;
map1[0] = -1;
int curr_remainder = 0;
// Stores required answer
int res = INT_MAX;
for (int i = 0; i < n; i++) {
// Add current element to
// curr_sum and take mod
curr_remainder = (curr_remainder
+ arr[i] + k)
% k;
// Update current
// remainder index
map1[curr_remainder] = i;
int mod
= (curr_remainder
- target_remainder
+ k)
% k;
// If mod already exists in map
// the subarray exists
if (map1.find(mod) !=
map1.end()) {
// Update res
res = min(res, i - map1[mod]);
}
}
// If not possible
if (res == INT_MAX || res == n) {
res = -1;
}
// Return the result
return res;
}
// Function to find the smallest submatrix
// rqured to be deleted to make the sum
// of the matrix divisible by K
int smstSubmatDeleted(vector > &mat,
int N, int M, int K)
{
// Stores the sum of
// element of the matrix
int S = 0;
// Traverse the matrix mat[][]
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++)
// Update S
S += mat[i][j];
}
// Stores smallest area need to be
// deleted to get sum divisible by K
int min_area = N * M;
// Stores leftmost column
// of each matrix
int left = 0;
// Stores rightmost column
// of each matrix
int right = 0;
// Stores number of coulmns
// deleted of a matrix
int width;
// Store area of the deleted matrix
int area;
// prefixRowSum[i]: Store sum of sub matrix
// whose topmost left and bottommost right
// position is (0, left) (i, right)
int prefixRowSum[N];
// Iterate over all possible values
// of (left, right)
for (left = 0; left < M; left++) {
// Initialize all possible values
// of prefixRowSum[] to 0
memset(prefixRowSum, 0,
sizeof(prefixRowSum));
for (right = left; right < M; right++) {
// Traverse each row from
// left to right column
for (int i = 0; i < N; i++) {
// Update row_sum[i];
prefixRowSum[i]
+= mat[i][right];
}
// Update width
width = removeSmallestSubarray(
prefixRowSum, S, N, K);
// If no submatrix of the length
// (right - left + 1) found to get
// the required output
if (width != -1) {
// Update area
area = (right - left + 1)
* (width);
// If area is less than min_area
if (area < min_area) {
// Update min_area
min_area = area;
}
}
}
}
return min_area;
}
// Driver Code
int main()
{
vector > mat
= { { 6, 2, 6 },
{ 3, 2, 8 },
{ 2, 5, 3 } };
int K = 3;
// Stores number of rows
// in the matrix
int N = mat.size();
// Stores number of column
// in the matrix
int M = mat[0].size();
cout<< smstSubmatDeleted(mat, N, M, K);
return 0;
}
Java
// Java program to implement
// the above approach
import java.util.*;
class GFG{
// Function to find the length of the
// smallest subarray to be removed such
// that sum of elements is equal to S % K
static int removeSmallestSubarray(int arr[], int S,
int n, int k)
{
// Remainder when total_sum
// is divided by K
int target_remainder = S % k;
// Stores curr_remainder and the
// most recent index at which
// curr_remainder has occured
HashMap map1 =
new HashMap<>();
map1.put(0, -1);
int curr_remainder = 0;
// Stores required answer
int res = Integer.MAX_VALUE;
for (int i = 0; i < n; i++)
{
// Add current element to
// curr_sum and take mod
curr_remainder = (curr_remainder +
arr[i] + k) % k;
// Update current
// remainder index
map1.put(curr_remainder, i);
int mod = (curr_remainder -
target_remainder +
k) % k;
// If mod already exists in map
// the subarray exists
if (map1.containsKey(mod))
{
// Update res
res = Math.min(res, i -
map1.get(mod));
}
}
// If not possible
if (res == Integer.MAX_VALUE ||
res == n)
{
res = -1;
}
// Return the result
return res;
}
// Function to find the smallest submatrix
// rqured to be deleted to make the sum
// of the matrix divisible by K
static int smstSubmatDeleted(int[][]mat,
int N, int M,
int K)
{
// Stores the sum of
// element of the matrix
int S = 0;
// Traverse the matrix mat[][]
for (int i = 0; i < N; i++)
{
for (int j = 0; j < M; j++)
// Update S
S += mat[i][j];
}
// Stores smallest area need
// to be deleted to get sum
// divisible by K
int min_area = N * M;
// Stores leftmost column
// of each matrix
int left = 0;
// Stores rightmost column
// of each matrix
int right = 0;
// Stores number of coulmns
// deleted of a matrix
int width;
// Store area of the deleted
// matrix
int area;
// prefixRowSum[i]: Store sum
// of sub matrix whose topmost
// left and bottommost right
// position is (0, left) (i, right)
int []prefixRowSum = new int[N];
// Iterate over all possible
// values of (left, right)
for (left = 0; left < M; left++)
{
// Initialize all possible
// values of prefixRowSum[]
// to 0
Arrays.fill(prefixRowSum, 0);
for (right = left;
right < M; right++)
{
// Traverse each row from
// left to right column
for (int i = 0; i < N; i++)
{
// Update row_sum[i];
prefixRowSum[i] +=
mat[i][right];
}
// Update width
width = removeSmallestSubarray(
prefixRowSum, S, N, K);
// If no submatrix of the
// length (right - left + 1)
// found to get the required
// output
if (width != -1)
{
// Update area
area = (right - left + 1) *
(width);
// If area is less than
// min_area
if (area < min_area)
{
// Update min_area
min_area = area;
}
}
}
}
return min_area;
}
// Driver Code
public static void main(String[] args)
{
int[][] mat = {{6, 2, 6},
{3, 2, 8},
{2, 5, 3}};
int K = 3;
// Stores number of rows
// in the matrix
int N = mat.length;
// Stores number of column
// in the matrix
int M = mat[0].length;
System.out.print(
smstSubmatDeleted(mat, N,
M, K));
}
}
// This code is contributed by Rajput-Ji
Python3
# Python3 program to implement
# the above approach
import sys
# Function to find the length of the
# smallest subarray to be removed such
# that sum of elements is equal to S % K
def removeSmallestSubarray(arr, S, n, k):
# Remainder when total_sum
# is divided by K
target_remainder = S % k
# Stores curr_remainder and the
# most recent index at which
# curr_remainder has occured
map1 = {}
map1[0] = -1
curr_remainder = 0
# Stores required answer
res = sys.maxsize
for i in range(n):
# Add current element to
# curr_sum and take mod
curr_remainder = (curr_remainder +
arr[i] + k) % k
# Update current
# remainder index
map1[curr_remainder] = i
mod = (curr_remainder -
target_remainder + k) % k
# If mod already exists in map
# the subarray exists
if (mod in map1):
# Update res
res = min(res, i - map1[mod])
# If not possible
if (res == sys.maxsize or res == n):
res = -1
# Return the result
return res
# Function to find the smallest submatrix
# rqured to be deleted to make the sum
# of the matrix divisible by K
def smstSubmatDeleted(mat, N, M, K):
# Stores the sum of
# element of the matrix
S = 0
# Traverse the matrix mat[][]
for i in range(N):
for j in range(M):
# Update S
S += mat[i][j]
# Stores smallest area need to be
# deleted to get sum divisible by K
min_area = N * M
# Stores leftmost column
# of each matrix
left = 0
# Stores rightmost column
# of each matrix
right = 0
# Stores number of coulmns
# deleted of a matrix
width = 0
# Store area of the deleted matrix
area = 0
# prefixRowSum[i]: Store sum of sub matrix
# whose topmost left and bottommost right
# position is (0, left) (i, right)
prefixRowSm = [0] * N
# Iterate over all possible values
# of (left, right)
for left in range(M):
# Initialize all possible values
# of prefixRowSum[] to 0
prefixRowSum = [0] * N
for right in range(left, M):
# Traverse each row from
# left to right column
for i in range(N):
# Update row_sum[i]
prefixRowSum[i] += mat[i][right]
# Update width
width = removeSmallestSubarray(
prefixRowSum, S, N, K)
# If no submatrix of the length
# (right - left + 1) found to get
# the required output
if (width != -1):
# Update area
area = (right - left + 1) * (width)
# If area is less than min_area
if (area < min_area):
# Update min_area
min_area = area
return min_area
# Driver Code
if __name__ == '__main__':
mat = [ [ 6, 2, 6 ],
[ 3, 2, 8 ],
[ 2, 5, 3 ] ]
K = 3
# Stores number of rows
# in the matrix
N = len(mat)
# Stores number of column
# in the matrix
M = len(mat[0])
print(smstSubmatDeleted(mat, N, M, K))
# This code is contributed by mohit kumar 29
C#
// C# program to implement
// the above approach
using System;
using System.Collections.Generic;
class GFG{
// Function to find the length of the
// smallest subarray to be removed such
// that sum of elements is equal to S % K
static int removeSmallestSubarray(int []arr, int S,
int n, int k)
{
// Remainder when total_sum
// is divided by K
int target_remainder = S % k;
// Stores curr_remainder and the
// most recent index at which
// curr_remainder has occured
Dictionary map1 = new Dictionary();
map1.Add(0, -1);
int curr_remainder = 0;
// Stores required answer
int res = int.MaxValue;
for(int i = 0; i < n; i++)
{
// Add current element to
// curr_sum and take mod
curr_remainder = (curr_remainder +
arr[i] + k) % k;
// Update current
// remainder index
map1[curr_remainder]= i;
int mod = (curr_remainder -
target_remainder +
k) % k;
// If mod already exists in map
// the subarray exists
if (map1.ContainsKey(mod))
{
// Update res
res = Math.Min(res, i -
map1[mod]);
}
}
// If not possible
if (res == int.MaxValue ||
res == n)
{
res = -1;
}
// Return the result
return res;
}
// Function to find the smallest submatrix
// rqured to be deleted to make the sum
// of the matrix divisible by K
static int smstSubmatDeleted(int[,]mat,
int N, int M,
int K)
{
// Stores the sum of
// element of the matrix
int S = 0;
// Traverse the matrix [,]mat
for(int i = 0; i < N; i++)
{
for(int j = 0; j < M; j++)
// Update S
S += mat[i,j];
}
// Stores smallest area need
// to be deleted to get sum
// divisible by K
int min_area = N * M;
// Stores leftmost column
// of each matrix
int left = 0;
// Stores rightmost column
// of each matrix
int right = 0;
// Stores number of coulmns
// deleted of a matrix
int width;
// Store area of the deleted
// matrix
int area;
// prefixRowSum[i]: Store sum
// of sub matrix whose topmost
// left and bottommost right
// position is (0, left) (i, right)
int []prefixRowSum = new int[N];
// Iterate over all possible
// values of (left, right)
for(left = 0; left < M; left++)
{
// Initialize all possible
// values of prefixRowSum[]
// to 0
for(int i = 0; i < prefixRowSum.Length; i++)
prefixRowSum[i] = 0;
for(right = left;
right < M; right++)
{
// Traverse each row from
// left to right column
for(int i = 0; i < N; i++)
{
// Update row_sum[i];
prefixRowSum[i] += mat[i, right];
}
// Update width
width = removeSmallestSubarray(
prefixRowSum, S, N, K);
// If no submatrix of the
// length (right - left + 1)
// found to get the required
// output
if (width != -1)
{
// Update area
area = (right - left + 1) *
(width);
// If area is less than
// min_area
if (area < min_area)
{
// Update min_area
min_area = area;
}
}
}
}
return min_area;
}
// Driver Code
public static void Main(String[] args)
{
int[,] mat = { { 6, 2, 6 },
{ 3, 2, 8 },
{ 2, 5, 3 } };
int K = 3;
// Stores number of rows
// in the matrix
int N = mat.GetLength(0);
// Stores number of column
// in the matrix
int M = mat.GetLength(1);
Console.Write(
smstSubmatDeleted(mat, N,
M, K));
}
}
// This code is contributed by shikhasingrajput
输出:
2
时间复杂度: O(M 2 * N)
辅助空间: O(N)