📌  相关文章
📜  总和小于或等于K的最大尺寸正方形子矩阵

📅  最后修改于: 2021-04-29 01:32:39             🧑  作者: Mango

给定大小为M x N且具有正整数和数字K的Matrix arr [] [] ,任务是找到元素之和小于或等于K的最大平方子矩阵的大小。

例子:

Input: 
arr[][] = { { 1, 1, 3, 2, 4, 3, 2 },
            { 1, 1, 3, 2, 4, 3, 2 },
            { 1, 1, 3, 2, 4, 3, 2 } },
K = 4
Output: 
2
Explanation:
Maximum size square Sub-Matrix 
with sum less than or equals to 4
      1 1
      1 1
Size is 2.

Input: 
arr[][] = { { 1, 1, 3, 2, 4, 3, 2 },
            { 1, 1, 3, 2, 4, 3, 2 },
            { 1, 1, 3, 2, 4, 3, 2 } }, 
K = 22
Output: 
3
Explanation:
Maximum size square Sub-Matrix 
with sum less than or equals to 22
      1 1 3
      1 1 3
      1 1 3
Size is 3. 

方法:

  1. 对于给定的矩阵arr [] []创建一个前缀和矩阵(例如sum [] [] ),使得sum [i] [j]存储大小为ixj的矩阵所有元素的和。
  2. 对于使用二进制搜索的前缀总和矩阵sum [] []中的每一行,请执行以下操作:
    • 进行二进制搜索,下限为0 ,上限为方矩阵的最大大小
    • 找到中间索引(例如mid )。
    • 如果大小为mid的所有可能方阵的元素之和小于或等于K ,则将下限更新为mid +1,以找到大小大于mid的最大和。
    • 否则将上限更新为中– 1,以找到大小小于中的最大和。
  3. 对于上述给定的有效条件,请在每次迭代中不断更新方阵的最大大小。

下面是上述方法的实现:

C++
// C++ program for the above approach
 
#include 
using namespace std;
 
// Function to find the maximum size
// of matrix with sum <= K
void findMaxMatrixSize(vector > arr, int K)
{
 
    int i, j;
 
    // N size of rows and M size of cols
    int n = arr.size();
    int m = arr[0].size();
 
    // To store the prefix sum of matrix
    int sum[n + 1][m + 1];
 
    // Create Prefix Sum
    for (int i = 0; i <= n; i++) {
 
        // Traverse each rows
        for (int j = 0; j <= m; j++) {
 
            if (i == 0 || j == 0) {
                sum[i][j] = 0;
                continue;
            }
 
            // Update the prefix sum
            // till index i x j
            sum[i][j] = arr[i - 1][j - 1] + sum[i - 1][j]
                        + sum[i][j - 1] - sum[i - 1][j - 1];
        }
    }
 
    // To store the maximum size of
    // matrix with sum <= K
    int ans = 0;
 
    // Traverse the sum matrix
    for (i = 1; i <= n; i++) {
 
        for (j = 1; j <= m; j++) {
 
            // Index out of bound
            if (i + ans - 1 > n || j + ans - 1 > m)
                break;
 
            int mid, lo = ans;
 
            // Maximum possible size
            // of matrix
            int hi = min(n - i + 1, m - j + 1);
 
            // Binary Search
            while (lo < hi) {
 
                // Find middle index
                mid = (hi + lo + 1) / 2;
 
                // Check whether sum <= K
                // or not
                // If Yes check for other
                // half of the search
                if (sum[i + mid - 1][j + mid - 1]
                        + sum[i - 1][j - 1]
                        - sum[i + mid - 1][j - 1]
                        - sum[i - 1][j + mid - 1]
                    <= K) {
                    lo = mid;
                }
 
                // Else check it in first
                // half
                else {
                    hi = mid - 1;
                }
            }
 
            // Update the maximum size matrix
            ans = max(ans, lo);
        }
    }
 
    // Print the final answer
    cout << ans << endl;
}
 
// Driver Code
int main()
{
    vector > arr;
 
    arr = { { 1, 1, 3, 2, 4, 3, 2 },
            { 1, 1, 3, 2, 4, 3, 2 },
            { 1, 1, 3, 2, 4, 3, 2 } };
 
    // Given target sum
    int K = 4;
 
    // Function Call
    findMaxMatrixSize(arr, K);
    return 0;
}


Java
// Java program for the above approach
import java.util.*;
 
class GFG {
 
    // Function to find the maximum size
    // of matrix with sum <= K
    static void findMaxMatrixSize(int[][] arr, int K)
    {
        int i, j;
 
        // N size of rows and M size of cols
        int n = arr.length;
        int m = arr[0].length;
 
        // To store the prefix sum of matrix
        int[][] sum = new int[n + 1][m + 1];
 
        // Create prefix sum
        for (i = 0; i <= n; i++) {
 
            // Traverse each rows
            for (j = 0; j <= m; j++) {
                if (i == 0 || j == 0) {
                    sum[i][j] = 0;
                    continue;
                }
 
                // Update the prefix sum
                // till index i x j
                sum[i][j] = arr[i - 1][j - 1]
                            + sum[i - 1][j] + sum[i][j - 1]
                            - sum[i - 1][j - 1];
            }
        }
 
        // To store the maximum size of
        // matrix with sum <= K
        int ans = 0;
 
        // Traverse the sum matrix
        for (i = 1; i <= n; i++) {
            for (j = 1; j <= m; j++) {
 
                // Index out of bound
                if (i + ans - 1 > n || j + ans - 1 > m)
                    break;
 
                int mid, lo = ans;
 
                // Maximum possible size
                // of matrix
                int hi = Math.min(n - i + 1, m - j + 1);
 
                // Binary Search
                while (lo < hi) {
 
                    // Find middle index
                    mid = (hi + lo + 1) / 2;
 
                    // Check whether sum <= K
                    // or not
                    // If Yes check for other
                    // half of the search
                    if (sum[i + mid - 1][j + mid - 1]
                            + sum[i - 1][j - 1]
                            - sum[i + mid - 1][j - 1]
                            - sum[i - 1][j + mid - 1]
                        <= K) {
                        lo = mid;
                    }
 
                    // Else check it in first
                    // half
                    else {
                        hi = mid - 1;
                    }
                }
 
                // Update the maximum size matrix
                ans = Math.max(ans, lo);
            }
        }
 
        // Print the final answer
        System.out.print(ans + "\n");
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        int[][] arr = { { 1, 1, 3, 2, 4, 3, 2 },
                        { 1, 1, 3, 2, 4, 3, 2 },
                        { 1, 1, 3, 2, 4, 3, 2 } };
 
        // Given target sum
        int K = 4;
 
        // Function Call
        findMaxMatrixSize(arr, K);
    }
}
 
// This code is contributed by 29AjayKumar


Python3
# Python3 program for the above approach
 
# Function to find the maximum size
# of matrix with sum <= K
 
 
def findMaxMatrixSize(arr, K):
 
    # N size of rows and M size of cols
    n = len(arr)
    m = len(arr[0])
 
    # To store the prefix sum of matrix
    sum = [[0 for i in range(m + 1)] for j in range(n + 1)]
 
    # Create Prefix Sum
    for i in range(n + 1):
 
        # Traverse each rows
        for j in range(m+1):
            if (i == 0 or j == 0):
                sum[i][j] = 0
                continue
 
            # Update the prefix sum
            # till index i x j
            sum[i][j] = arr[i - 1][j - 1] + sum[i - 1][j] + \
                sum[i][j - 1]-sum[i - 1][j - 1]
 
    # To store the maximum size of
    # matrix with sum <= K
    ans = 0
 
    # Traverse the sum matrix
    for i in range(1, n + 1):
        for j in range(1, m + 1):
 
            # Index out of bound
            if (i + ans - 1 > n or j + ans - 1 > m):
                break
 
            mid = ans
            lo = ans
 
            # Maximum possible size
            # of matrix
            hi = min(n - i + 1, m - j + 1)
 
            # Binary Search
            while (lo < hi):
 
                # Find middle index
                mid = (hi + lo + 1) // 2
 
                # Check whether sum <= K
                # or not
                # If Yes check for other
                # half of the search
                if (sum[i + mid - 1][j + mid - 1] +
                    sum[i - 1][j - 1] -
                    sum[i + mid - 1][j - 1] -
                        sum[i - 1][j + mid - 1] <= K):
                    lo = mid
 
                # Else check it in first
                # half
                else:
                    hi = mid - 1
 
            # Update the maximum size matrix
            ans = max(ans, lo)
 
    # Print the final answer
    print(ans - 1)
 
 
# Driver Code
if __name__ == '__main__':
    arr = [[1, 1, 3, 2, 4, 3, 2],
           [1, 1, 3, 2, 4, 3, 2],
           [1, 1, 3, 2, 4, 3, 2]]
 
    # Given target sum
    K = 4
 
    # Function Call
    findMaxMatrixSize(arr, K)
 
# This code is contributed by Surendra_Gangwar


C#
// C# program for the above approach
using System;
 
class GFG {
 
    // Function to find the maximum size
    // of matrix with sum <= K
    static void findMaxMatrixSize(int[, ] arr, int K)
    {
        int i, j;
 
        // N size of rows and M size of cols
        int n = arr.GetLength(0);
        int m = arr.GetLength(1);
 
        // To store the prefix sum of matrix
        int[, ] sum = new int[n + 1, m + 1];
 
        // Create prefix sum
        for (i = 0; i <= n; i++) {
 
            // Traverse each rows
            for (j = 0; j <= m; j++) {
                if (i == 0 || j == 0) {
                    sum[i, j] = 0;
                    continue;
                }
 
                // Update the prefix sum
                // till index i x j
                sum[i, j] = arr[i - 1, j - 1]
                            + sum[i - 1, j] + sum[i, j - 1]
                            - sum[i - 1, j - 1];
            }
        }
 
        // To store the maximum size
        // of matrix with sum <= K
        int ans = 0;
 
        // Traverse the sum matrix
        for (i = 1; i <= n; i++) {
            for (j = 1; j <= m; j++) {
 
                // Index out of bound
                if (i + ans - 1 > n || j + ans - 1 > m)
                    break;
 
                int mid, lo = ans;
 
                // Maximum possible size
                // of matrix
                int hi = Math.Min(n - i + 1, m - j + 1);
 
                // Binary Search
                while (lo < hi) {
 
                    // Find middle index
                    mid = (hi + lo + 1) / 2;
 
                    // Check whether sum <= K
                    // or not
                    // If Yes check for other
                    // half of the search
                    if (sum[i + mid - 1, j + mid - 1]
                            + sum[i - 1, j - 1]
                            - sum[i + mid - 1, j - 1]
                            - sum[i - 1, j + mid - 1]
                        <= K) {
                        lo = mid;
                    }
 
                    // Else check it in first
                    // half
                    else {
                        hi = mid - 1;
                    }
                }
 
                // Update the maximum size matrix
                ans = Math.Max(ans, lo);
            }
        }
 
        // Print the readonly answer
        Console.Write(ans + "\n");
    }
 
    // Driver Code
    public static void Main(String[] args)
    {
        int[, ] arr = { { 1, 1, 3, 2, 4, 3, 2 },
                        { 1, 1, 3, 2, 4, 3, 2 },
                        { 1, 1, 3, 2, 4, 3, 2 } };
 
        // Given target sum
        int K = 4;
 
        // Function Call
        findMaxMatrixSize(arr, K);
    }
}
 
// This code is contributed by Amit Katiyar


输出
2

时间复杂度: O(N * N * log(N))
辅助空间: O(M * N)