给定一个维度为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)
高效的方法:可以使用类似于在二维矩阵中找到最大和矩形的方法来优化上述方法。唯一的区别是矩形的总和不能超过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)
如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live