📜  对于矩阵的任何矩形,最大和不能超过K

📅  最后修改于: 2021-05-17 18:40:02             🧑  作者: Mango

给定尺寸为N * M的矩阵mat [] []和整数K ,任务是从给定的矩阵中找到任何矩形的最大和,该矩阵的元素之和最多为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)