美团2024年春招第一场笔试【技术】-小美的平衡矩阵
发表于更新于
阅读量:33 深圳
开发生涯java面试题美团2024年春招第一场笔试【技术】-小美的平衡矩阵
GodProgrammerMan平衡矩阵
小美拿到了一个 n∗n 的矩阵,其中每个元素是 0 或者 1。
小美认为一个矩形区域是完美的,当且仅当该区域内 0 的数量恰好等于 1 的数量。
现在,小美希望你回答有多少个 i∗i 的完美矩形区域。你需要回答 1≤i≤n 的所有答案。
输入描述:
1 2 3
| 第一行输入一个正整数n,代表矩阵大小。 接下来的n行,每行输入一个长度为n的 01 串,用来表示矩阵。 1\leq n \leq 200
|
输出描述:
1
| 输出n行,第i行输出i*i的完美矩形区域的数量。
|
实例
1 2 3 4 5 6 7 8 9 10 11
| 输入例子: 4 1010 0101 1100 0011 输出例子: 0 7 0 1
|
解题思路
- 前缀和计算:我们需要构建一个二维数组来保存从 (0,0) 到 (i,j) 的区域中 1 和 0 的数量之差。这样我们就可以通过矩形区域的差值来判断是否为完美矩形。
- 矩形枚举:通过枚举不同尺寸的矩形,检查每个矩形区域内 1 和 0 的数量是否相等。
Java 实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| import java.util.Scanner;
public class PerfectRectangle { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); int n = scanner.nextInt(); scanner.nextLine();
int[][] matrix = new int[n][n]; for (int i = 0; i < n; i++) { String line = scanner.nextLine(); for (int j = 0; j < n; j++) { matrix[i][j] = line.charAt(j) - '0'; } }
int[][] diff = new int[n + 1][n + 1];
for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) { int val = matrix[i - 1][j - 1] == 1 ? 1 : -1; diff[i][j] = diff[i - 1][j] + diff[i][j - 1] - diff[i - 1][j - 1] + val; } }
for (int size = 1; size <= n; size++) { int count = 0;
for (int i = size; i <= n; i++) { for (int j = size; j <= n; j++) { int total = diff[i][j] - diff[i - size][j] - diff[i][j - size] + diff[i - size][j - size]; if (total == 0) { count++; } } }
System.out.println(count); } } }
|
详细解释
前缀和差值矩阵 diff:diff[i][j] 表示从左上角到 (i-1, j-1) 的矩形区域中,1 和 0 的数量差值。我们使用 1 表示 1,使用 -1 表示 0,因此如果某个子矩形区域的差值为 0,说明这个区域内 1 和 0 的数量相等,即为一个完美矩形。
矩形枚举:对于每个尺寸 size 的矩形,我们遍历所有可能的起点 (i, j),通过前缀和差值快速计算出矩形内的 1 和 0 的数量。如果差值为 0,则这个矩形为完美矩形。