如何提取二维数组的反对角线(Anti-Diagonal)分组序列

本文详解如何用纯二维数组实现反对角线元素的逐层提取:针对 n×n 矩阵,将每条从左下到右上的对角线(即反对角线)作为独立一维数组,按从左上到右下顺序组装成二维结果数组。重点剖析内层循环的索引映射逻辑与边界控制机制。

在二维数组中,“反对角线”(anti-diagonal)特指所有满足 行索引 + 列索引 = 常数 的元素集合。但本题要求的并非单条主反对角线(如 x[0][2], x[1][1], x[2][0]),而是全部平行反对角线——即按“和值”从小到大分组的所有斜向线段。以 3×3 示例为例:

{{1,2,3},
 {4,5,6},
 {7,8,9}}

其反对角线分组依据是 i + j 的和值(注意:此处 i 为行、j 为列):

  • 和 = 0 → [0][0] → {1}
  • 和 = 1 → [0][1], [1][0] → {2,4}
  • 和 = 2 → [0][2], [1][1], [2][0] → {3,5,7}
  • 和 = 3 → [1][2], [2][1] → {6,8}
  • 和 = 4 → [2][2] → {9}

共 2n−1 = 5 条线,对应结果数组 res 的 5 行。

外层循环 for (int i = 0; i 并非原数组行号,而是目标结果的行序号(即反对角线索引),它实际对应上述“和值”:sum = i。而内层循环正是围绕这一和值,枚举所有满足 row + col == i 的合法 (row, col) 组合。

关键看内层循环:

for (int j = i, r = 0; j >= 0 && r < res[i].length; j--) {
    if ((i - j) < x.length && j < x.length) {
        res[i][r] = x[i - j][j];
        r++;
    }
}
  • j 是列索引(col),从 i 开始递减(j--);
  • i - j 就是行索引(row),因为 row + col = i ⇒ row = i - col = i - j;
  • 因此 x[i - j][j] 恰好访问所有满足 row + col == i 的元素,按 col 从大到小(即从右上向左下)遍历该反对角线;
  • r 是当前结果行 res[i] 的列指针,确保填入位置正确;
  • if 条件 (i - j)

✅ 举例验证 i = 2(第三行结果,对应和值=2):

  • j 初始为 2 → row = 2-2 = 0, col = 2 → x[0][2] = 3 ✔️
  • j = 1 → row = 1, col = 1 → x[1][1] = 5 ✔️
  • j = 0 → row = 2, col = 0 → x[2][0] = 7 ✔️
  • j = -1 → 循环终止。
    结果 res[2] = {3,5,7},完全符合预期。

⚠️ 注意事项:

  • 该算法假设输入为方阵(x.length == x[0].length),若为矩形需调整边界条件;
  • s 的计算(i
  • 使用 ArrayList 虽

    更直观,但本实现严格遵循题目对原生二维数组的要求,体现了对索引数学关系的精准把握。

掌握 row = i - j 这一映射,就抓住了反对角线遍历的核心——它把斜向访问转化为两个线性变量的协同运动,是数组几何变换的经典范式。