Maximum Side Length of a Square with Sum Less than or Equal to Threshold in C++


Suppose we have a m x n matrix mat and an integer threshold. We have to the maximum side-length of a square with a sum less than or equal to the given threshold or return 0 if there is no such square. So if the input is like −

1132432
1132432
1132432


1132432
1132432
1132432

And threshold is 4, then output will be 2, as there are two squares of side length 2, so max is 2

To solve this, we will follow these steps −

  • Define a method called ok, this will take x and matrix m and threshold th
  • set curr := 0
  • for i in range x – 1 to number of rows of mat – 1
    • for c in range x – 1 to number of cols of mat – 1
      • curr := mat[r, c]
      • if c – x >= 0, then decrease curr by mat[r, c – x]
      • if r – x >= 0, then decrease curr by mat[r - x, c]
      • if c – x >= 0 and r – x >= 0, then increase curr by mat[r – x, c - x]
      • if curr <= th, then return true
  • return false
  • In the main method, it will take matrix and threshold
  • r := number of rows, c := number of columns, low := 1, high := min of r and c, ans := 0
  • for i in range 1 to c – 1
    • for j in range 0 to c – 1
      • increase mat[j, i] by mat[j, i - 1]
  • for i in range 1 to r – 1
    • for j in range 0 to c – 1
      • increase mat[j, i] by mat[ i - 1,j]
  • while low <= high:
    • mid := low + (high - low) / 2
    • if of(mid, mat, th), then ans := mid and low := mid + 1, otherwise high := mid – 1
  • return ans

Example(C++)

Let us see the following implementation to get a better understanding −

 Live Demo

#include <bits/stdc++.h>
using namespace std;
typedef long long int lli;
class Solution {
public:
   bool ok(int x, vector < vector<int> >& mat, int th){
      lli current = 0;
      for(int r = x - 1; r < mat.size(); r++){
         for(int c = x - 1; c < mat[0].size(); c++){
            current = mat[r][c];
            if(c - x >= 0)current -= mat[r][c-x];
            if(r -x >= 0)current -= mat[r - x][c];
            if(c - x >= 0 && r - x >= 0)current += mat[r-x][c-x];
            if(current <= th)return true;
         }
      }
      return false;
   }
   int maxSideLength(vector<vector<int>>& mat, int th) {
      int r = mat.size();
      int c = mat[0].size();
      int low = 1;
      int high = min(r, c);
      int ans = 0;
      for(int i = 1; i < c; i++){
         for(int j = 0; j < r; j++){
            mat[j][i] += mat[j][i - 1];
         }
      }
      for(int i = 1; i < r; i++){
         for(int j = 0; j < c; j++){
            mat[i][j] += mat[i - 1][j];
         }
      }
      while(low <= high){
         int mid = low + ( high - low ) / 2;
         if(ok(mid, mat, th)){
            ans = mid;
            low = mid + 1;
         }
         else{
            high = mid - 1;
         }
      }
      return ans;
   }
};
main(){
   vector<vector<int>> v = {{1,1,3,2,4,3,2},{1,1,3,2,4,3,2},{1,1,3,2,4,3,2}};
   Solution ob;
   cout << (ob.maxSideLength(v, 4));
}

Input

[[1,1,3,2,4,3,2],[1,1,3,2,4,3,2],[1,1,3,2,4,3,2]]
4

Output

2

Updated on: 30-Apr-2020

141 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements