← 中文资源

简体中文版本

原地旋转 90 度的方阵

通过转置再翻转行,在 O(1) 额外空间内顺时针或逆时针旋转方阵,并校验矩阵形状。

阅读英文原文

功能说明

该示例用转置加翻转的方式原地旋转二维方阵。顺时针旋转等价于先沿主对角线交换元素,再反转每一行;逆时针旋转则在转置后反转行顺序。函数返回同一个矩阵引用,便于链式处理,且额外空间为常数,适合图像像素块、棋盘、游戏地图等不允许整块复制的场景。

关键代码

函数先校验方向取值,再校验每一行都是长度等于行数的数组,任何非方阵都会在修改前抛 RangeError,避免只旋转一半留下损坏数据。转置只遍历对角线右上三角,行列互换一次,防止重复交换把矩阵还原。顺时针分支对每行调用 reverse,逆时针分支反转行数组的顺序,两条路径都只使用原地操作。

使用注意

函数只支持二维方阵,M 乘 N 的矩形需要先确定目标尺寸并分配新矩阵。旋转会直接修改传入数组及其行数组,若调用方仍需原数据,应先做深拷贝。方向参数大小写敏感,拼写错误会抛错而不是静默按默认方向执行。元素本身不做复制,对象元素在旋转后仍是同一引用。空矩阵长度为零,会直接返回空数组。

验证方式

用三乘三矩阵测试顺时针,断言第一行变为原第一列的逆序;用同一矩阵测试逆时针,验证结果与顺时针三次一致;检查返回引用与输入相同;传入非方阵、含非数组行与非法方向,断言抛 RangeError;空矩阵返回自身;对旋转四次的结果与原始矩阵做深度比较。

代码示例

export function rotateMatrix(matrix, direction = "clockwise") {
  if (!Array.isArray(matrix)) throw new TypeError("matrix must be an array");
  if (direction !== "clockwise" && direction !== "counterclockwise") {
    throw new RangeError("direction must be clockwise or counterclockwise");
  }
  const size = matrix.length;
  for (const row of matrix) {
    if (!Array.isArray(row) || row.length !== size) {
      throw new RangeError("matrix must be square");
    }
  }

  for (let row = 0; row < size; row += 1) {
    for (let column = row + 1; column < size; column += 1) {
      const temporary = matrix[row][column];
      matrix[row][column] = matrix[column][row];
      matrix[column][row] = temporary;
    }
  }

  if (direction === "clockwise") {
    for (const row of matrix) row.reverse();
  } else {
    matrix.reverse();
  }
  return matrix;
}