1. 开心消消乐题目解析与Java实现
作为一名经历过多次华为OD机考的开发者,我深知这类题目对算法基础和编码能力的考察重点。今天要分享的"开心消消乐"题目,是华为OD双机位C卷中的经典题型,主要考察二维矩阵处理、深度优先搜索(DFS)或广度优先搜索(BFS)的应用能力。
1.1 题目核心要求
题目给定一个N行M列的二维矩阵,矩阵元素由0和1组成。我们需要找出所有相邻的1组成的区域(上下左右相邻视为连通),并消除这些区域。这里的"消除"可以理解为统计连通区域的数量或进行某种标记操作。
示例矩阵:
code复制1 1 0 0
0 0 0 1
0 0 1 1
在这个矩阵中,存在两个由1组成的连通区域:
- 左上角两个1组成的区域
- 右下角三个1组成的区域
1.2 解题思路分析
解决这类矩阵连通区域问题,通常有以下几种方法:
- 深度优先搜索(DFS):从一个1出发,递归探索其上下左右的相邻1,并标记已访问
- 广度优先搜索(BFS):使用队列实现,同样从某个1出发,逐层扩展探索相邻1
- 并查集(Union-Find):适合处理动态连通性问题,但在此题中可能略显复杂
考虑到华为OD机考对时间复杂度和空间复杂度的要求,DFS和BFS都是可行的选择。我个人更倾向于使用DFS,因为它的代码实现相对简洁,递归思路清晰。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. Java实现详解
2.1 基础数据结构准备
首先我们需要定义一些基础变量和数据结构:
java复制public class HappyElimination {
private static int rows;
private static int cols;
private static int[][] directions = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}}; // 上下左右四个方向
public static int countAreas(int[][] matrix) {
if (matrix == null || matrix.length == 0) return 0;
rows = matrix.length;
cols = matrix[0].length;
int count = 0;
boolean[][] visited = new boolean[rows][cols];
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
if (matrix[i][j] == 1 && !visited[i][j]) {
dfs(matrix, i, j, visited);
count++;
}
}
}
return count;
}
// 其他方法继续...
}
2.2 DFS算法实现
DFS的核心是递归探索相邻的1,并标记已访问的位置:
java复制private static void dfs(int[][] matrix, int i, int j, boolean[][] visited) {
if (i < 0 || i >= rows || j < 0 || j >= cols ||
matrix[i][j] == 0 || visited[i][j]) {
return;
}
visited[i][j] = true;
// 探索四个方向
for (int[]
