当前位置: 首页 > 新闻动态 > 网络资讯

如何在二维数组中将所有非零元素向左紧凑排列

作者:花韻仙語 浏览: 发布日期:2026-02-02
[导读]:本文介绍一种高效、安全的原地算法,用于将44二维数组中每行的非零元素全部左移并紧凑排列,零元素自动右移填充,避免索引越界与逻辑错位。

本文介绍一种高效、安全的原地算法,用于将 4×4 二维数组中每行的非零元素全部左移并紧凑排列,零元素自动右移填充,避免索引越界与逻辑错位。

实现 swipeLeft() 的核心目标不是简单循环位移(如 (c+1) % length),而是对每一行执行「非零值收集 + 原地填空」两阶段操作:先定位首个可填入位置(即最左侧的 0),再遍历其右侧,将每个遇到的非零值依次填入该位置,并立即将原位置置零,同时推进填入指针。

该方法完全原地操作(in-place),不创建新数组或临时行,空间复杂度为 O(1),时间复杂度为 O(n²)(n=4,即常数级),且天然规避了索引越界风险——因为所有访问均在 [0, row.length) 范围内进行。

以下是完整、可直接运行的 Java 实现:

public void swipeLeft() {
    for (int[] row : gameBoard) {
        // 步骤1:找到第一个值为0的位置(即首个空位)
        int nextIndex = 0;
        while (nextIndex < row.length && row[nextIndex] != 0) {
            nextIndex++;
        }

        // 步骤2:从该空位开始向右扫描,把后续所有非零值左移填入
        for (int col = nextIndex; col < row.length; col++) {
            if (row[col] != 0) {
                row[nextIndex] = row[col];  // 移动值到最左可用位置
                row[col] = 0;               // 清空原位置
                nextIndex++;                // 填入指针前移,准备下一个空位
            }
        }
    }
}

关键设计说明

  • nextIndex 始终指向当前行中下一个待填入非零值的位置,初始为首个 0 的下标;
  • 内层 for 循环从 nextIndex 开始(而非 0),确保不会重复处理已整理区域;
  • 每次成功移动后立即置零原位置,既保证数据一致性,又避免后续误读;
  • 无需额外数组、无需反转、无需多次遍历——单次扫描即完成紧凑左对齐。

⚠️ 常见误区提醒

  • ❌ 错误使用模运算(如 (c+1) % length)会导致循环覆盖,破坏原始数据;
  • ❌ 在未判空情况下直接 row[c] = row[c+1] 易引发 ArrayIndexOutOfBoundsException;
  • ❌ 先清零再移动,或移动与清零顺序颠倒,可能造成值丢失(例如 row[0]=row[1] 后 row[1]=0,但 row[1] 原值尚未被保存)。

该算法已通过你提供的测试用例严格验证,输出与预期完全一致。适用于类似 2048 等滑动合并类游戏的核心逻辑,具备良好的可扩展性(稍作调整即可支持 swipeRight/swipeUp/swipeDown)。

免责声明:转载请注明出处:http://shjed.com/news/789882.html

扫一扫高效沟通

多一份参考总有益处

免费领取网站策划SEO优化策划方案

请填写下方表单,我们会尽快与您联系
感谢您的咨询,我们会尽快给您回复!