Given a n × m grid, where n represents the number of row cells and m represents the number of column cells. Return the number of rectangles that can be formed within this grid.
Examples:
Input: n = 2, m = 2
Output: 9
Explanation:
There are 4 rectangles of size 1 x 1
There are 2 rectangles of size 1 x 2
There are 2 rectangles of size 2 x 1
There is 1 rectangle of size 2 x 2Input: n = 5, m = 4
Output: 150
Explanation: There are a total of 150 rectangles.
Table of Content
[Naive Approach] Brute Force - O(n ⨯ m) Time and O(1) Space
Consider every possible rectangle size (height × width). For each size, count the number of positions where it can be placed inside the n × m grid, and sum these counts over all possible dimensions.
Implementation steps:
- Iterate over all possible rectangle heights from 1 to n.
- For each height, iterate over all possible rectangle widths from 1 to m.
- For a rectangle of size i × j, compute the number of valid positions as (n - i + 1) × (m - j + 1).
- Add this value to the answer.
- Return the total count after all dimensions have been processed.
#include <bits/stdc++.h>
using namespace std;
int rectNum(int n, int m)
{
int count = 0;
// iterating over all possible pairs of horizontal lines
for (int i = 1; i <= n; i++)
{
// iterating over all possible pairs of vertical lines
for (int j = 1; j <= m; j++)
{
// counting the number of rectangles
// that can be formed using these lines
count += (n - i + 1) * (m - j + 1);
}
}
return count;
}
int main()
{
int n = 5, m = 4;
cout << rectNum(n, m);
return 0;
}
public class Main {
public static int rectNum(int n, int m) {
int count = 0;
// iterating over all possible pairs of horizontal lines
for (int i = 1; i <= n; i++) {
// iterating over all possible pairs of vertical lines
for (int j = 1; j <= m; j++) {
// counting the number of rectangles
// that can be formed using these lines
count += (n - i + 1) * (m - j + 1);
}
}
return count;
}
public static void main(String[] args) {
int n = 5, m = 4;
System.out.println(rectNum(n, m));
}
}
def rectNum(n, m):
count = 0
# iterating over all possible pairs of horizontal lines
for i in range(1, n + 1):
# iterating over all possible pairs of vertical lines
for j in range(1, m + 1):
# counting the number of rectangles
# that can be formed using these lines
count += (n - i + 1) * (m - j + 1)
return count
if __name__ == "__main__":
n = 5
m = 4
print(rectNum(n, m))
using System;
public class Program
{
public static int rectNum(int n, int m)
{
int count = 0;
// iterating over all possible pairs of horizontal lines
for (int i = 1; i <= n; i++)
{
// iterating over all possible pairs of vertical lines
for (int j = 1; j <= m; j++)
{
// counting the number of rectangles
// that can be formed using these lines
count += (n - i + 1) * (m - j + 1);
}
}
return count;
}
public static void Main()
{
int n = 5, m = 4;
Console.WriteLine(rectNum(n, m));
}
}
function rectNum(n, m) {
let count = 0;
// iterating over all possible pairs of horizontal lines
for (let i = 1; i <= n; i++) {
// iterating over all possible pairs of vertical lines
for (let j = 1; j <= m; j++) {
// counting the number of rectangles
// that can be formed using these lines
count += (n - i + 1) * (m - j + 1);
}
}
return count;
}
function main() {
let n = 5, m = 4;
console.log(rectNum(n, m));
}
main();
Output
150
[Expected Approach] Combinatorial Mathematics - O(1) Time and O(1) Space
A rectangle is uniquely determined by choosing its top and bottom horizontal grid lines and its left and right vertical grid lines. So, count the ways to choose 2 horizontal lines and 2 vertical lines, then multiply these counts.
Implementation steps:
- Compute the number of ways to choose 2 horizontal lines from the n + 1 horizontal grid lines: n * (n + 1) / 2.
- Compute the number of ways to choose 2 vertical lines from the m + 1 vertical grid lines: m * (m + 1) / 2.
- Multiply these two values to obtain the total number of rectangles.
- Return the result using the formula: n * (n + 1) * m * (m + 1) / 4.
#include <bits/stdc++.h>
using namespace std;
int rectNum(int n, int m) {
// selecting 2 horizontal edges out of n+1 = n*(n+1)/2
// selecting 2 vertical edges out of m+1 = m*(m+1)/2
// total ways = n*(n+1)/2 * m*(m+1)/2
return (m * n * (n + 1) * (m + 1)) / 4;
}
int main() {
int n = 5, m = 4;
cout << rectNum(n, m);
return 0;
}
public class Main {
public static int rectNum(int n, int m) {
// selecting 2 horizontal edges out of n+1 = n*(n+1)/2
// selecting 2 vertical edges out of m+1 = m*(m+1)/2
// total ways = n*(n+1)/2 * m*(m+1)/2
return (m * n * (n + 1) * (m + 1)) / 4;
}
public static void main(String[] args) {
int n = 5, m = 4;
System.out.println(rectNum(n, m));
}
}
def rectNum(n, m):
# selecting 2 horizontal edges out of n+1 = n*(n+1)/2
# selecting 2 vertical edges out of m+1 = m*(m+1)/2
# total ways = n*(n+1)/2 * m*(m+1)/2
return (m * n * (n + 1) * (m + 1)) // 4
n = 5
m = 4
print(rectNum(n, m))
using System;
public class Program {
// selecting 2 horizontal edges out of n+1 = n*(n+1)/2
// selecting 2 vertical edges out of m+1 = m*(m+1)/2
// total ways = n*(n+1)/2 * m*(m+1)/2
public static int rectNum(int n, int m) {
return (m * n * (n + 1) * (m + 1)) / 4;
}
public static void Main() {
int n = 5, m = 4;
Console.WriteLine(rectNum(n, m));
}
}
function rectNum(n, m) {
// selecting 2 horizontal edges out of n+1 = n*(n+1)/2
// selecting 2 vertical edges out of m+1 = m*(m+1)/2
// total ways = n*(n+1)/2 * m*(m+1)/2
return Math.floor((m * n * (n + 1) * (m + 1)) / 4);
}
let n = 5, m = 4;
console.log(rectNum(n, m));
Output
150