GGbond : 解析一道经典的js算法题(旋转图像)

180 阅读3分钟

详细解析LeetCode中的一道经典的js算法题:旋转图像

image.png

输入: matrix = [[1,2,3],[4,5,6],[7,8,9]]
输出: [[7,4,1],[8,5,2],[9,6,3]]

我们的目标是将一个n * n的二维矩阵顺时针旋转90度。解决这个问题的关键是找到矩阵中每个元素的新位置。我们可以通过以下步骤来解决这个问题:

  1. 将矩阵沿着主对角线翻转。
  2. 将矩阵沿着中心列翻转。

这两个步骤将矩阵旋转90度。接下来让我们详细讨论这两个步骤。

沿着主对角线翻转

要沿着主对角线翻转矩阵,我们可以使用两个循环嵌套来交换矩阵中的元素。具体来说,我们可以使用以下代码:

for(let i = 0; i < n; i++) {
  for(let j = i; j < n; j++) {
    [matrix[i][j], matrix[j][i]] = [matrix[j][i], matrix[i][j]];
  }
}

在上面的代码中,我们使用了ES6的解构语法来交换矩阵中的元素。通过嵌套的循环,我们可以遍历矩阵中每一个元素。对于每个元素,我们需要交换它和矩阵中对应位置的元素。具体来说,我们需要将矩阵中第i行第j列的元素和第j行第i列的元素交换。这样,我们就可以将矩阵沿着主对角线翻转。注意,我们只需要交换矩阵中对角线上方的元素,这就是为什么j的初始值为i。

沿着中心列翻转

要沿着中心列翻转矩阵,我们可以使用两个指针来交换矩阵中的列。具体来说,我们可以使用以下代码:

for(let i = 0; i < n; i++) {
  let left = 0, right = n - 1;
  while(left < right) {
    [matrix[i][left], matrix[i][right]] = [matrix[i][right], matrix[i][left]];
    left++;
    right--;
  }
}

在上面的代码中,我们使用了双指针来交换矩阵中的列。我们从左右两侧开始,交换对应位置的元素,直到两个指针相遇。具体来说,我们需要将矩阵中第i行第left列的元素和第i行第right列的元素交换。然后,我们将left指针向右移动一位,将right指针向左移动一位,继续交换对应位置的元素,直到left指针大于等于right指针。这样,我们就可以将矩阵沿着中心列翻转。

完整代码

const rotate = function(matrix) {
  const n = matrix.length;
  // 沿着主对角线翻转
  for(let i = 0; i < n; i++) {
    for(let j = i; j < n; j++) {
      [matrix[i][j], matrix[j][i]] = [matrix[j][i], matrix[i][j]];
    }
  }
  // 沿着中心列翻转
  for(let i = 0; i < n; i++) {
    let left = 0, right = n - 1;
    while(left < right) {
      [matrix[i][left], matrix[i][right]] = [matrix[i][right], matrix[i][left]];
      left++;
      right--;
    }
  }
  return matrix;
}

通过将矩阵沿着主对角线和中心列翻转我们可以将一个n * n的二维矩阵顺时针旋转90度。这是非常经典的js算法题,也是很多面试中的常客。希望通过本文的解析,大家能够更好地理解和掌握该问题的解法。