📌  相关文章
📜  矩阵的任何矩形的最大和不超过 K

📅  最后修改于: 2021-09-06 05:07:53             🧑  作者: Mango

给定一个维度为N * M的矩阵mat[][]和一个整数K ,任务是从给定的矩阵中找到任何可能的矩形的最大和,其元素之和至多为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