
本文详解 java 中对二维数组每行内相邻相同非零元素进行左向合并的实现方法,涵盖边界处理、逻辑优化与典型陷阱规避,并提供可直接运行的完整示例代码。
本文详解 java 中对二维数组每行内相邻相同非零元素进行左向合并的实现方法,涵盖边界处理、逻辑优化与典型陷阱规避,并提供可直接运行的完整示例代码。
在实现类似 2048 游戏中的“左滑合并”逻辑时,核心需求是:对二维数组每一行,从左到右扫描,若两个相邻元素值相等且非零,则将其合并为两倍值,置于左侧位置,右侧置为 0。注意:该操作仅作用于连续且未被其他合并影响的位置,且需严格避免数组越界。
原始代码中存在两个关键错误:
- 内层循环条件 col
- 合并后未跳过已处理位置,可能导致同一元素被重复参与合并(例如 [2,2,2,2] 理想结果应为 [4,0,4,0],而非 [4,4,0,0]),但本题要求的是单次扫描、仅合并首次相邻对(即贪心式左合并),因此无需复杂位移逻辑,只需修正边界即可。
✅ 正确实现的关键点:
所谓数组,就是相同数据类型的元素按一定顺序排列的集合,就是把有限个类型相同的变量用一个名字命名,然后用编号区分他们的变量的集合,这个名字称为数组名,编号称为下标。组成数组的各个变量称为数组的分量,也称为数组的元素,有时也称为下标变量。数组是在程序设计中,为了处理方便, 把具有相同类型的若干变量按有序的形式组织起来的一种形式。这些按序排列的同类数据元素的集合称为数组。 数组应用&二维数组目录 1. 数组的简单应用2. 数组排序3. 数组查找4. 数组的使用思想5. 查表法6. 二维数组7. 数组综合
- 内层循环上限设为 arr[i].length - 1,确保 j + 1 始终有效;
- 合并条件建议显式排除 0(虽 0 == 0 成立,但合并零无意义且违反游戏逻辑),即 arr[i][j] != 0 && arr[i][j] == arr[i][j + 1];
- 使用 arr[i][j] += arr[i][j + 1] 替代乘法,语义更清晰,且与答案中逻辑一致。
以下是完整、健壮的参考实现:
import java.util.Arrays;
public class ArrayMerger {
public static void mergeAdjacentLeft(int[][] board) {
if (board == null) return;
for (int i = 0; i < board.length; i++) {
// 每行单独处理
for (int j = 0; j < board[i].length - 1; j++) {
// 仅合并非零的相邻相等元素
if (board[i][j] != 0 && board[i][j] == board[i][j + 1]) {
board[i][j] *= 2; // 左侧元素翻倍
board[i][j + 1] = 0; // 右侧清零
}
}
}
}
public static void main(String[] args) {
int[][] board = {
{0, 2, 4, 2},
{0, 0, 2, 2},
{2, 2, 0, 0},
{0, 5, 0, 2},
{2, 2, 2, 2}, // 验证多对场景
{2, 2, 2, 0}
};
mergeAdjacentLeft(board);
System.out.println(Arrays.deepToString(board));
// 输出:
// [[0, 2, 4, 2], [0, 0, 4, 0], [4, 0, 0, 0], [0, 5, 0, 2], [4, 0, 4, 0], [4, 0, 2, 0]]
}
}⚠️ 注意事项:
- 本实现为单轮合并(即每个元素至多参与一次合并),符合题目示例行为;若需支持连击合并(如 [2,2,2] → [4,2,0] → [8,0,0]),则需额外添加“压缩空格 + 再次扫描”步骤;
- 合并操作会改变原数组,如需保留原始数据,请先深拷贝;
- 若扩展为四方向合并(上/下/右),需分别调整索引遍历顺序与比较方向(如向上合并则比较 board[i][j] 与 board[i-1][j])。
总结:安全合并相邻元素的核心在于精准控制索引范围与明确业务约束条件(如忽略零值)。通过修正循环边界、增强条件判断,即可稳定实现预期逻辑,为构建更复杂的数组变换系统打下坚实基础。









