给定尺寸为N * M的矩阵mat [] []和整数K ,任务是从给定的矩阵中找到任何矩形的最大和,该矩阵的元素之和最多为K。
例子:
Input: mat[][] ={{1, 0, 1}, {0, -2, 3}}, K = 2
Output: 2
Explanation: The maximum sum possible in any rectangle from the matrix is 2 (<= K), obtained from the matrix {{0, 1}, {-2, 3}}.
Input: mat[][] = {{2, 2, -1}}, K = 3
Output: 3
Explanation: The maximum sum rectangle is {{2, 2, -1}} is 3 ( <- K).
天真的方法:最简单的方法是检查给定矩阵中所有可能的子矩阵,其元素之和是否最多为K。如果发现为真,则存储该子矩阵的总和。最后,打印获得的此类子矩阵的最大和。
时间复杂度: O(N 6 )
辅助空间: O(1)
高效方法:可以通过使用类似于在2D矩阵中找到最大和矩形的方法来优化上述方法。唯一的区别是矩形的总和不得超过K。想法是一一固定左列和右列,并在每次迭代中,将每行的总和存储在当前矩形中,并找到此数组中小于K的最大子数组总和。请按照以下步骤解决问题:
- 初始化一个变量,例如res ,该变量存储子矩阵的最大和为K的元素的最大和。
- 使用左列的变量i在[0,M – 1]范围内进行迭代,并执行以下步骤:
- 初始化大小为N的数组V [] ,以存储左右一对列之间的每一行的元素之和。
- 遍历范围 [0,M – 1]在右列中使用变量j并执行以下步骤:
- 找到每行当前左列和右列之间的总和,并更新数组V []中的总和。
- 在V []中找到总和小于K的最大总和子数组,并将结果存储在ans中。
- 如果ans的值大于res的值,则将res更新为ans 。
- 完成上述步骤后,打印res的值作为结果。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to find the maximum possible
// sum of arectangle which is less than K
int maxSubarraySum(vector& sum,
int k, int row)
{
int curSum = 0, curMax = INT_MIN;
// Stores the values (cum_sum - K)
set sumSet;
// Insert 0 into the set sumSet
sumSet.insert(0);
// Traverse over the rows
for (int r = 0; r < row; ++r) {
// Get cumulative sum from [0 to i]
curSum += sum[r];
// Search for upperbound of
// (cSum - K) in the hashmap
auto it = sumSet.lower_bound(curSum - k);
// If upper_bound of (cSum - K)
// exists, then update max sum
if (it != sumSet.end()) {
curMax = max(curMax,
curSum - *it);
}
// Insert cummulative value
// in the hashmap
sumSet.insert(curSum);
}
// Return the maximum sum
// which is less than K
return curMax;
}
// Function to find the maximum sum of
// rectangle such that its sum is no
// larger than K
void maxSumSubmatrix(
vector >& matrix, int k)
{
// Stores the number of rows
// and columns
int row = matrix.size();
int col = matrix[0].size();
// Store the required result
int ret = INT_MIN;
// Set the left column
for (int i = 0; i < col; ++i) {
vector sum(row, 0);
// Set the right column for the
// left column set by outer loop
for (int j = i; j < col; ++j) {
// Calculate sum between the
// current left and right
// for every row
for (int r = 0; r < row; ++r) {
sum[r] += matrix[r][j];
}
// Stores the sum of rectangle
int curMax = maxSubarraySum(
sum, k, row);
// Update the overall maximum sum
ret = max(ret, curMax);
}
}
// Print the result
cout << ret;
}
// Driver Code
int main()
{
vector > matrix
= { { 1, 0, 1 }, { 0, -2, 3 } };
int K = 2;
// Function Call
maxSumSubmatrix(matrix, K);
return 0;
}
Java
// Java program for the above approach
import java.io.*;
import java.util.*;
class GFG{
// Function to find the maximum possible
// sum of arectangle which is less than K
static int maxSubarraySum(int[] sum,
int k, int row)
{
int curSum = 0, curMax = Integer.MIN_VALUE;
// Stores the values (cum_sum - K)
Set sumSet = new HashSet();
// Insert 0 into the set sumSet
sumSet.add(0);
// Traverse over the rows
for(int r = 0; r < row; ++r)
{
// Get cumulative sum from [0 to i]
curSum += sum[r];
// Search for upperbound of
// (cSum - K) in the hashmap
ArrayList list = new ArrayList();
list.addAll(sumSet);
int it = list.lastIndexOf(curSum - k);
// If upper_bound of (cSum - K)
// exists, then update max sum
if (it >-1)
{
curMax = Math.max(curMax,
curSum - it);
}
// Insert cummulative value
// in the hashmap
sumSet.add(curSum);
}
// Return the maximum sum
// which is less than K
return curMax;
}
// Function to find the maximum sum of
// rectangle such that its sum is no
// larger than K
static void maxSumSubmatrix(int[][] matrix, int k)
{
// Stores the number of rows
// and columns
int row = matrix.length;
int col = matrix[0].length;
// Store the required result
int ret = Integer.MIN_VALUE;
// Set the left column
for(int i = 0; i < col; ++i)
{
int[] sum = new int[row];
// Set the right column for the
// left column set by outer loop
for(int j = i; j < col; ++j)
{
// Calculate sum between the
// current left and right
// for every row
for(int r = 0; r < row; ++r)
{
sum[r] += matrix[r][j];
}
// Stores the sum of rectangle
int curMax = maxSubarraySum(
sum, k, row);
// Update the overall maximum sum
ret = Math.max(ret, curMax);
}
}
// Print the result
System.out.print(ret);
}
// Driver Code
public static void main (String[] args)
{
int[][] matrix = { { 1, 0, 1 },
{ 0, -2, 3 } };
int K = 2;
// Function Call
maxSumSubmatrix(matrix, K);
}
}
// This code is contributed by avanitrachhadiya2155
Python3
# Python3 program for the above approach
from bisect import bisect_left, bisect_right
import sys
# Function to find the maximum possible
# sum of arectangle which is less than K
def maxSubarraySum(sum, k, row):
curSum, curMax = 0, -sys.maxsize - 1
# Stores the values (cum_sum - K)
sumSet = {}
# Insert 0 into the set sumSet
sumSet[0] = 1
# Traverse over the rows
for r in range(row):
# Get cumulative sum from [0 to i]
curSum += sum[r]
# Search for upperbound of
# (cSum - K) in the hashmap
arr = list(sumSet.keys())
it = bisect_left(arr, curSum - k)
# If upper_bound of (cSum - K)
# exists, then update max sum
if (it != len(arr)):
curMax = max(curMax, curSum - it)
# Insert cummulative value
# in the hashmap
sumSet[curSum] = 1
# Return the maximum sum
# which is less than K
return curMax
# Function to find the maximum sum of
# rectangle such that its sum is no
# larger than K
def maxSumSubmatrix(matrix, k):
# Stores the number of rows
# and columns
row = len(matrix)
col = len(matrix[0])
# Store the required result
ret = -sys.maxsize - 1
# Set the left column
for i in range(col):
sum = [0] * (row)
# Set the right column for the
# left column set by outer loop
for j in range(i, col):
# Calculate sum between the
# current left and right
# for every row
for r in range(row):
sum[r] += matrix[r][j]
# Stores the sum of rectangle
curMax = maxSubarraySum(sum, k, row)
# Update the overall maximum sum
ret = max(ret, curMax)
# Print the result
print(ret)
# Driver Code
if __name__ == '__main__':
matrix = [ [ 1, 0, 1 ], [ 0, -2, 3 ] ]
K = 2
# Function Call
maxSumSubmatrix(matrix, K)
# This code is contributed by mohit kumar 29
C#
// C# program for the above approach
using System;
using System.Collections.Generic;
class GFG{
// Function to find the maximum possible
// sum of arectangle which is less than K
static int maxSubarraySum(int[] sum,int k, int row)
{
int curSum = 0, curMax = Int32.MinValue;
// Stores the values (cum_sum - K)
HashSet sumSet = new HashSet();
// Insert 0 into the set sumSet
sumSet.Add(0);
// Traverse over the rows
for(int r = 0; r < row; ++r)
{
// Get cumulative sum from [0 to i]
curSum += sum[r];
// Search for upperbound of
// (cSum - K) in the hashmap
List list = new List();
list.AddRange(sumSet);
int it = list.LastIndexOf(curSum - k);
// If upper_bound of (cSum - K)
// exists, then update max sum
if (it > -1)
{
curMax = Math.Max(curMax,
curSum - it);
}
// Insert cummulative value
// in the hashmap
sumSet.Add(curSum);
}
// Return the maximum sum
// which is less than K
return curMax;
}
// Function to find the maximum sum of
// rectangle such that its sum is no
// larger than K
static void maxSumSubmatrix(int[,] matrix, int k)
{
// Stores the number of rows
// and columns
int row = matrix.GetLength(0);
int col = matrix.GetLength(1);
// Store the required result
int ret = Int32.MinValue;
// Set the left column
for(int i = 0; i < col; ++i)
{
int[] sum = new int[row];
// Set the right column for the
// left column set by outer loop
for(int j = i; j < col; ++j)
{
// Calculate sum between the
// current left and right
// for every row
for(int r = 0; r < row; ++r)
{
sum[r] += matrix[r, j];
}
// Stores the sum of rectangle
int curMax = maxSubarraySum(
sum, k, row);
// Update the overall maximum sum
ret = Math.Max(ret, curMax);
}
}
// Print the result
Console.Write(ret);
}
// Driver Code
static public void Main()
{
int[,] matrix = { { 1, 0, 1 },
{ 0, -2, 3 } };
int K = 2;
// Function Call
maxSumSubmatrix(matrix, K);
}
}
// This code is contributed by rag2127
输出:
2
时间复杂度: O(N 3 * log(N))
辅助空间: O(N)